package com.authine.cloudpivot.ext.applicationservice;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.data.support.SqlWithParams;
import com.authine.cloudpivot.ext.constants.*;
import com.authine.cloudpivot.ext.dao.Inquiry;
import com.authine.cloudpivot.ext.dao.InquiryGoods;
import com.authine.cloudpivot.ext.dto.DemandPoolDto;
import com.authine.cloudpivot.ext.dto.GoodsPurchaseDto;
import com.authine.cloudpivot.ext.dto.inquiry.*;
import com.authine.cloudpivot.ext.dto.pricing.InquiryGoodsEntityListDto;
import com.authine.cloudpivot.ext.dto.pricing.ListEndInquiryDto;
import com.authine.cloudpivot.ext.dto.pricing.ListPricingDto;
import com.authine.cloudpivot.ext.dto.quotation.QuotationGoodsDto;
import com.authine.cloudpivot.ext.dto.system.DepartmentDto;
import com.authine.cloudpivot.ext.dto.system.OrganizationDto;
import com.authine.cloudpivot.ext.dto.system.TriggerMetaDto;
import com.authine.cloudpivot.ext.dto.system.UserDto;
import com.authine.cloudpivot.ext.enums.inquiry.*;
import com.authine.cloudpivot.ext.enums.system.OrganizationAttributeEnum;
import com.authine.cloudpivot.ext.exception.InquiryException;
import com.authine.cloudpivot.ext.utils.*;
import com.authine.cloudpivot.ext.utils.message.MessageUtils;
import com.authine.cloudpivot.ext.utils.premission.PermissionUtils;
import com.authine.cloudpivot.ext.utils.system.*;
import com.authine.cloudpivot.ext.vo.InquiryGoodsClarifyVo;
import com.authine.cloudpivot.ext.vo.InquiryGoodsVo;
import com.authine.cloudpivot.ext.vo.InquiryVo;
import com.authine.cloudpivot.ext.vo.QuotationGoodsVo;
import com.authine.common.util.DateUtils;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.common.SchemaHelper;
import com.authine.mvp.app.launcher.common.TableHelper;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.query.expression.Operator;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName InquiryService
 * @Description: 我的询价
 * @Author fj
 * @Date 2021/4/9
 * @Version V1.0
 **/
@Path("InquiryService")
@Slf4j
public class InquiryService extends ApplicationService {
    private static final TableHelper tableHelper = ApplicationContextUtils.getBean(TableHelper.class);
    private static final NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);
    private static final VendorGoodsMatchedQuotationService vendorGoodsMatchedQuotationService = new VendorGoodsMatchedQuotationService();
    private static final QuotationService quotationService = new QuotationService();
    private static final String inquiryName = getTableName(ModelConst.T_INQUIRY);
    private static final String inquiryGoodsName = getTableName(ModelConst.T_INQUIRY_GOODS);
    private static final String quotationGoodsName = getTableName(ModelConst.T_QUOTATION_GOODS);

    private final static String GE = "通用电气水电设备（中国）有限公司";
    private final static String HZGE = "通用电气能源（杭州）有限公司";
    private final static String MYSP = "牧原食品股份有限公司";

    /**
     * 保存询价单
     *
     * @param inquiry 询价单参数
     * @return 保存询价单后结果
     */
    @Path("saveInquiry")
    @POST
    @Operation(summary = "保存询价单", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> saveInquiry(@Parameter CreateInquiryDto inquiry) {
        SessionUser sessionUser = new SessionUser();
        log.info("-------------------RequestContext：{}--------------------", RequestContext.get().toString());
        try {
            saveAndUpdateCheck(inquiry);
        } catch (InquiryException e) {
            e.printStackTrace();
            return SingleResponse.error(e.getErrCode(), e.getErrMsg());
        }

        // 获取当前登录组织信息
        List<SelectorFormat> selectorFormatList = sessionUser.get().getOrganization_id();
        String currentOrgId = selectorFormatList.get(0).getId();
        String currentOrgName = selectorFormatList.get(0).getName();

        // 判断是否开启定标审批
        boolean pickAttribute = OrgAttributeUtils.isEnabledAttribute(currentOrgId, OrganizationAttributeEnum.PICKET_AGE_APPROVAL);

        // 判断是否开启订单审批
        boolean orderAttribute = OrgAttributeUtils.isEnabledAttribute(currentOrgId, OrganizationAttributeEnum.ORDER_APPROVAL);
        if (StringUtils.isEmpty(inquiry.getCost_center_id())) {
            if (pickAttribute) {
                if (GE.equals(currentOrgName)) {
                    throw new BizException("您已开启定标审批，请选择成本中心！");
                }
            } else if (orderAttribute) {
                if (HZGE.equals(currentOrgName)) {
                    throw new BizException("您已开启订单审批，请选择成本中心！");
                }
            }
        }
        StringBuilder sql = new StringBuilder();
        Map<String, Object> parameter = Maps.newHashMap();
        sql.append("select max(i.createdTime) from\n");
        sql.append(inquiryName).append(" i \n");
        sql.append("where i.member_id = :memberId");
        parameter.put("memberId", inquiry.getMember_id());
        log.info("sql = {}, parameters = {}", sql, JSONObject.toJSONString(parameter));
        Date latestTime;
        try {
            latestTime = jdbcTemplate.queryForObject(sql.toString(), parameter, Date.class);
        } catch (DataAccessException e) {
            latestTime = null;
            e.printStackTrace();
        }
        if (latestTime != null) {
            if ((System.currentTimeMillis() - latestTime.getTime()) > 5000) {
                return SingleResponse.error("-18", "防止恶意操作,5秒之内不能创建新的询价单");
            }
        }
        // 获取用户信息
        UserDto user = UserUtils.getUserByUserId(RequestContext.getCorpLoginId());

        // 获取部门信息
        DepartmentDto dept = DeptUtils.getDeptByDeptId(user.getDepartment_id().get(0).getId());

        // 获取组织信息
        OrganizationDto org = OrgUtils.getOrgByOrgId(user.getOrganization_id().get(0).getId());

        DepartmentDto targetDept = DeptUtils.getDeptByDeptId(inquiry.getTarget_department_id().get(0).getId());
        if (targetDept == null) {
            throw new BizException("需求部门不存在");
        }
        // 判断外部来源询价Id是否已存在
        String currentClientID = sessionUser.getCurrentClientID();
        if (!StringUtils.isEmpty(inquiry.getClient_inquiry_id()) && !"gomro_api".equals(currentClientID) && !"gomro_ios".equals(currentClientID)) {
            sql = new StringBuilder();
            parameter = Maps.newHashMap();
            sql.append("select count(i.id) from\n");
            sql.append(inquiryName).append(" i \n");
            sql.append("where i.client_inquiry_id = :clientInquiryId\n");
            sql.append("and i.member_id -> '$.id' = :memberId");
            parameter.put("clientInquiryId", inquiry.getClient_inquiry_id());
            parameter.put("memberId", inquiry.getMember_id().get(0).getId());
            log.info("sql = {}, parameters = {}", sql, JSONObject.toJSONString(parameter));
            Integer count = jdbcTemplate.queryForObject(sql.toString(), parameter, Integer.class);
            if (count != null && count > 0) {
                throw new BizException("来源询价单id:" + inquiry.getClient_inquiry_id() + "已存在!");
            }
        }
        if (org.getStatement_cycle() == null || org.getStatement_cycle() <= 0) {
            return SingleResponse.error("-19", "当前客户没有账期，请联系平台管理员！");
        }
        // 保存询价单 WRITE_MAP_NULL_FEATURES
        inquiry.setId(SchemaHelper.getId());
        inquiry.setMember_name(user.getFullname());
        inquiry.setUser_name(user.getUsername());
        inquiry.setDepartment_name(dept.getName());
        inquiry.setOrganization_company_name(org.getName());
        inquiry.setAccount_period(org.getStatement_cycle());
        inquiry.setTarget_department_name(inquiry.getTarget_department_id().get(0).getName());
        // 询价商品中冗余字段赋值，保存询价人和询价人组织
        inquiry.getC5uxuiw5i4qo().forEach(goods -> {
            // 生成id
            goods.setId(SchemaHelper.getId());
            goods.setMember_name(user.getFullname());
            goods.setOrganization_company_name(org.getName());
            goods.setAccount_period(org.getStatement_cycle());
        });
        SelectorFormat orgSelectorFormat = new SelectorFormat();
        orgSelectorFormat.setType(1);
        orgSelectorFormat.setId(org.getId());
        orgSelectorFormat.setName(org.getName());

        SelectorFormat deptSelectorFormat = new SelectorFormat();
        deptSelectorFormat.setType(1);
        deptSelectorFormat.setId(dept.getId());
        deptSelectorFormat.setName(dept.getName());

        SelectorFormat userSelectorFormat = new SelectorFormat();
        userSelectorFormat.setType(3);
        userSelectorFormat.setId(user.getId());
        userSelectorFormat.setName(user.getFullname());

        inquiry.setOrganization_id(Collections.singletonList(orgSelectorFormat));
        inquiry.setMember_id(Collections.singletonList(userSelectorFormat));
        inquiry.setDepartment_id(Collections.singletonList(deptSelectorFormat));

        Map<String, Object> inquiryMap = BeanUtils.bean2Map(inquiry);
        // 询价商品也需要转成map
        List<Map<String, Object>> inquiryGoodsList = Lists.newArrayList();
        inquiry.getC5uxuiw5i4qo().forEach(goods -> inquiryGoodsList.add(BeanUtils.bean2Map(goods)));
        inquiryMap.put("c5uxuiw5i4qo", inquiryGoodsList);
        log.info("------------------------创建询价单数据：{}------------------------", JSONObject.toJSONString(inquiryMap));
        SingleResponse<BO> inquiryResult = BoServiceUtils.createBo(ModelConst.T_INQUIRY, Collections.singletonList(inquiryMap));
        if (!inquiryResult.isSuccess()) {
            return SingleResponse.error("-20", "保存询价单失败，请稍后重试");
        }
        // 发送消息给个人中心
        List<String> messageParams = Collections.singletonList(String.format("发布了一个询价，询价单号【%s】，请查看！", inquiryResult.getData().getBizObjectId()));
        MessageUtils.createdSystemMessage(messageParams);

        // 询价方式为邀请或邀请加全平台公开时，必须选择供应商，保存到询价单和供应商中间表中
        if (VendorScopeEnum.SOME.getCode().equals(inquiry.getVendor_scope()) || VendorScopeEnum.SOME_AND_ALL.getCode().equals(inquiry.getVendor_scope())) {
            // 添加id为1的平台组织，用于供应商报价的时候，平台可以看到
            inquiry.getInquiryVendorIdList().add(0, PlatformConst.ORGANIZATION_ID);
            List<Map<String, Object>> inquiryVendorList = Lists.newArrayList();
            Map<String, Object> inquiryVendorMap;
            List<OrganizationDto> vendorList = OrgUtils.getOrgListByOrgIds(inquiry.getInquiryVendorIdList());
            if (CollectionUtils.isEmpty(vendorList)) {
                return SingleResponse.error("-21", "操作失败:当前询价方式包含邀请,必须选择邀请的供应商");
            }
            for (OrganizationDto vendor : vendorList) {
                inquiryVendorMap = Maps.newHashMap();
                inquiryVendorMap.put("inquiry_id", inquiryResult.getData().getBizObjectId());
                inquiryVendorMap.put("vendor_organization_id", vendor.createSelectorFormat());
                inquiryVendorList.add(inquiryVendorMap);
            }
            SingleResponse<BO> inquiryVendorResult = BoServiceUtils.createBo(ModelConst.T_INQUIRY_VENDOR, inquiryVendorList);
            log.info("------------------------创建询价单供应商中间表数据成功，返回结果：{}------------------------", JSONObject.toJSONString(inquiryVendorResult));
            if (!inquiryVendorResult.isSuccess()) {
                return SingleResponse.error("-22", "保存询价单供应商数据失败，请稍后重试");
            }
        }
        // 如果是通过系统api操作，只有保存操作，保存时需要提交定时任务
        if (!StringUtils.isEmpty(currentClientID)) {
            inquiryCloseScheduler(inquiryMap);
        }
        return inquiryResult;
    }

    /**
     * 更新询价单
     *
     * @param inquiry 询价单参数
     * @return 更新询价单后结果
     */
    @Path("updateInquiry")
    @POST
    @Operation(summary = "更新询价单", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateInquiry(@Parameter CreateInquiryDto inquiry) {
        try {
            saveAndUpdateCheck(inquiry);
        } catch (InquiryException e) {
            e.printStackTrace();
            return SingleResponse.error(e.getErrCode(), e.getErrMsg());
        }
        if (StringUtils.isEmpty(inquiry.getId())) {
            return SingleResponse.error("-18", "询价单号不能为空");
        }
        String[] columnNames = new String[]{"inquiry_goods_status", "inquiry_id"};
        Operator[] operators = new Operator[]{Operator.IN, Operator.EQ};
        Object[] columnValues = new Object[]{Arrays.asList(InquiryStatusEnum.INQUIRY_GOODS_1_APPROVE.getCode(),
                InquiryStatusEnum.INQUIRY_GOODS_3_QUOTING.getCode(), InquiryStatusEnum.INQUIRY_GOODS_4_END.getCode(),
                InquiryStatusEnum.INQUIRY_GOODS_5_CLOSE.getCode()), inquiry.getId()};

        SingleResponse<BOList> inquiryGoodsBOList = BoServiceUtils.findListByComplex(ModelConst.T_INQUIRY_GOODS, columnNames, columnValues, operators);
        log.info("------------------------通过询价单id和询价商品状态获取询价商品列表：{}------------------------", JSONObject.toJSONString(inquiryGoodsBOList));

        if (inquiryGoodsBOList.getData().getTotal() > 0) {
            return SingleResponse.error("-19", "操作失败:询价单号" + inquiry.getId() + "中存在非新建和已退回状态的询价商品");
        }
        // 修改询价单
        Map<String, Object> inquiryMap = BeanUtils.bean2Map(inquiry);
        // 询价商品也需要转成map
        List<Map<String, Object>> inquiryGoodsList = Lists.newArrayList();
        inquiry.getC5uxuiw5i4qo().forEach(goods -> inquiryGoodsList.add(BeanUtils.bean2Map(goods)));
        inquiryMap.put("c5uxuiw5i4qo", inquiryGoodsList);
        SingleResponse<BO> inquiryResult = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY, inquiryMap);
        log.info("------------------------更新询价单数据成功，更新后结果：{}------------------------", JSONObject.toJSONString(inquiryResult));

        // 更新询价单和供应商中间表
        if (!inquiryResult.isSuccess()) {
            return SingleResponse.error("-20", "保存询价单失败，请稍后重试");
        }
        // 询价方式为邀请或邀请加全平台公开时，必须选择供应商，保存到询价单和供应商中间表中
        if (VendorScopeEnum.SOME.getCode().equals(inquiry.getVendor_scope()) || VendorScopeEnum.SOME_AND_ALL.getCode().equals(inquiry.getVendor_scope())) {
            // 删除旧数据
            SingleResponse<BOList> inquiryVendorResultList = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_VENDOR, "inquiry_id", inquiry.getId());
            log.info("------------------------根据询价单id获取询价单供应商中间表数据：{}------------------------", JSONObject.toJSONString(inquiryVendorResultList));

            List<String> bizObjectIds = Lists.newArrayList();
            for (Map<String, Object> inquiryVendor : inquiryVendorResultList.getData().getData()) {
                bizObjectIds.add(String.valueOf(inquiryVendor.get("id")));
            }
            if (!CollectionUtils.isEmpty(bizObjectIds)) {
                Response response = BoServiceUtils.batchDeleteBO(ModelConst.T_INQUIRY_VENDOR, bizObjectIds, true);
                log.info("------------------------删除之前的询价单供应商中间表数据成功，删除数据：{}------------------------", JSONObject.toJSONString(response));

                if (!response.isSuccess()) {
                    return SingleResponse.error("-21", "更新询价单供应商数据失败，请稍后重试");
                }
            }
            // 添加id为1的平台组织，用于供应商报价的时候，平台可以看到
            inquiry.getInquiryVendorIdList().add(0, PlatformConst.ORGANIZATION_ID);
            List<Map<String, Object>> inquiryVendorList = Lists.newArrayList();
            Map<String, Object> inquiryVendorMap;
            List<OrganizationDto> vendorList = OrgUtils.getOrgListByOrgIds(inquiry.getInquiryVendorIdList());
            if (CollectionUtils.isEmpty(vendorList)) {
                return SingleResponse.error("-21", "操作失败:当前询价方式包含邀请,必须选择邀请的供应商");
            }
            for (OrganizationDto vendor : vendorList) {
                inquiryVendorMap = Maps.newHashMap();
                inquiryVendorMap.put("inquiry_id", inquiryResult.getData().getBizObjectId());
                inquiryVendorMap.put("vendor_organization_id", vendor.createSelectorFormat());
                inquiryVendorList.add(inquiryVendorMap);
            }
            SingleResponse<BO> inquiryVendorResult = BoServiceUtils.createBo(ModelConst.T_INQUIRY_VENDOR, inquiryVendorList);
            log.info("------------------------创建询价单供应商中间表数据成功，返回结果：{}------------------------", JSONObject.toJSONString(inquiryVendorResult));
            if (!inquiryVendorResult.isSuccess()) {
                return SingleResponse.error("-22", "保存询价单供应商数据失败，请稍后重试");
            }
        }
        return inquiryResult;
    }

    /**
     * 提交询价单
     *
     * @param inquiry 询价单信息
     * @return 询价单提交后结果
     */
    @Path("submitInquiry")
    @POST
    @Operation(summary = "提交询价单", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> submitInquiry(@Parameter InquiryDto inquiry) {
        // todo 判断是否开启审批，开启审批状态变为审批中，没有开启审批状态状态变为报价中
        if (CollectionUtils.isEmpty(inquiry.getInquiryIdList())) {
            return SingleResponse.error("-1", "询价单号不能为空");
        }
        // 获取询价单信息
        SingleResponse<BOList> inquiryResultList = BoServiceUtils.findListByIn(ModelConst.T_INQUIRY, "id", inquiry.getInquiryIdList());
        log.info("------------------------根据询价单id获取询价单列表数据：{}------------------------", JSONObject.toJSONString(inquiryResultList));
        if (!inquiryResultList.isSuccess()) {
            return SingleResponse.error("-2", "获取询价单信息失败，请选择正确的询价单号");
        }

        List<CreateInquiryGoodsDto> matchInquiryGoods = Lists.newArrayList();
        SingleResponse<BO> updateInquiryResult = null;
        SingleResponse<BOList> inquiryGoodsResultList;
        SingleResponse<BO> updateInquiryGoodsResult;
        Map<String, Object> inquiryDataMap;
        List<Map<String, Object>> inquiryGoodsDataList = Lists.newArrayList();
        for (Map<String, Object> inquiryResultMap : inquiryResultList.getData().getData()) {
            // 获取询价商品信息
            inquiryGoodsResultList = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, "inquiry_id", inquiryResultMap.get("id"));
            log.info("------------------------根据询价单获取询价商品列表数据：{}------------------------", JSONObject.toJSONString(inquiryGoodsResultList));
            if (!inquiryGoodsResultList.isSuccess()) {
                return SingleResponse.error("-4", "获取询价商品信息失败，请选择正确的询价单号");
            }
            if (inquiryGoodsResultList.getData().getTotal() == 0) {
                return SingleResponse.error("-5", "操作失败:询价单号" + inquiryResultMap.get("id") + "不存在需要提交的商品");
            }
            for (Map<String, Object> inquiryGoodsResultMap : inquiryGoodsResultList.getData().getData()) {
                if (!InquiryStatusEnum.INQUIRY_GOODS_2_APPROVE_NO.getCode().equals(inquiryGoodsResultMap.get("inquiry_goods_status")) &&
                        !InquiryStatusEnum.INQUIRY_GOODS_0_NEW.getCode().equals(inquiryGoodsResultMap.get("inquiry_goods_status"))) {
                    return SingleResponse.error("-6", "操作失败:该询价商品" + inquiryGoodsResultMap.get("id") + "非新建或打回状态，暂时无法更改！！！");
                }
            }
            // 更新询价单
            inquiryDataMap = Maps.newHashMap();
            inquiryDataMap.put("id", inquiryResultMap.get("id"));
            inquiryDataMap.put("release_time", new Date());
            updateInquiryResult = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY, inquiryDataMap);
            log.info("------------------------更新询价单数据成功，更新后结果：{}------------------------", JSONObject.toJSONString(updateInquiryResult));
            // 更新询价商品
            inquiryGoodsResultList.getData().getData().forEach(map -> {
                Map<String, Object> inquiryGoodsDataMap = Maps.newHashMap();
                inquiryGoodsDataMap.put("id", map.get("id"));
                inquiryGoodsDataMap.put("inquiry_goods_status", InquiryStatusEnum.INQUIRY_GOODS_3_QUOTING.getCode());
                // 运营中心需要的冗余字段，其余字段在前端处理
                inquiryGoodsDataMap.put("inquiry_release_time", new Date());
                inquiryGoodsDataList.add(inquiryGoodsDataMap);
            });
            updateInquiryGoodsResult = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY_GOODS, inquiryGoodsDataList);
            log.info("------------------------更新询价商品数据成功，更新后结果：{}------------------------", JSONObject.toJSONString(updateInquiryGoodsResult));
            // 审核中的询价和整单询价不会进入平台报价
            if ("0".equals(String.valueOf(inquiryResultMap.get("quote_total_strategy")))) {
                matchInquiryGoods.addAll(JSONUtil.toList(JSONUtil.parseArray(inquiryGoodsResultList.getData().getData()), CreateInquiryGoodsDto.class));
            }
            //提交询价单获取定时任务
            log.info("询价单验证是否需要创建定时任务:询价单单号：{},商品状态状态：{}", inquiryResultMap.get("id"), inquiryGoodsResultList.getData().getData().get(0).get("inquiry_goods_status"));
            inquiryCloseScheduler(inquiryResultMap);
            log.info("询价单定时触发器创建成功:询价单单号：{}", inquiryResultMap.get("id"));
        }
        // todo 创建询价站内推送信   publishMessage

        // todo 根据组织ID获取该组织邀请的组织电话列表，并发送短信  pushByInvitation

        if (!matchInquiryGoods.isEmpty()) {
            // todo 发送kafka消息   searchModelFromVendorGoods
            vendorGoodsMatchedQuotationService.generateQuotationListByInquiryGoods(matchInquiryGoods, null, true);
        }
        return updateInquiryResult;
    }

    /**
     * 保存并提交询价单
     *
     * @param inquiry 询价单请求参数
     * @return 询价单响应结果
     */
    @Path("saveAndSubmitInquiry")
    @POST
    @Operation(summary = "保存并提交询价单", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> saveAndSubmitInquiry(@Parameter CreateInquiryDto inquiry) {
        try {
            saveAndUpdateCheck(inquiry);
        } catch (InquiryException e) {
            e.printStackTrace();
            return SingleResponse.error(e.getErrCode(), e.getErrMsg());
        }

        SingleResponse<BO> saveOrUpdate;
        if (StringUtils.isEmpty(inquiry.getId())) {
            saveOrUpdate = saveInquiry(inquiry);
        } else {
            saveOrUpdate = updateInquiry(inquiry);
        }
        if (!saveOrUpdate.isSuccess()) {
            return SingleResponse.error(saveOrUpdate.getErrCode(), saveOrUpdate.getErrMessage());
        }
        InquiryDto inquiryDto = new InquiryDto();
        inquiryDto.setInquiryIdList(Collections.singletonList(saveOrUpdate.getData().getBizObjectId()));

        SingleResponse<BO> submit = submitInquiry(inquiryDto);
        if (!submit.isSuccess()) {
            return SingleResponse.error("-19", "提交询价单失败");
        }
        //去重询价商品
        inquiry.setId(saveOrUpdate.getData().getBizObjectId());
        dupliRemoveInquiryGoods(inquiry);
        // 全部供应商报价、多次购买，开启平台自动报价。满足条件后进入自动报价
        // todo 判断是否开启平台报价，目前没有属性，默认为true
        if (inquiry.getQuote_multiple_purchases()
                && VendorScopeEnum.ALL.getCode().equals(String.valueOf(inquiry.getVendor_scope()))) {
            // todo 发送kafka消息
            autoMatchQuotation(inquiry);
        }
        return saveOrUpdate;
    }

    /**
     * 询价商品去重
     *
     * @param inquiry 询价单参数
     * @return 询价商品去重后结果
     */
    @Path("dupliRemoveInquiryGoods")
    @POST
    @Operation(summary = "询价商品去重", tags = CUSTOM_SERVICE)
    public void dupliRemoveInquiryGoods(@Parameter CreateInquiryDto inquiry) {
        // todo 判断是不是牧原组织
        log.info("-------------------RequestContext：{}--------------------", RequestContext.get().toString());
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> dataMap;
        for (CreateInquiryGoodsDto inquiryGoods : inquiry.getC5uxuiw5i4qo()) {
            StringBuffer sql = new StringBuffer("SELECT ctg.*,sti.id as inquiryId,sig.id as inquiryGoodsId\n" +
                    "        from commoditymaterials.i_commoditymaterials_t_goods_purchase ctg left join sourcingcenter.i_sourcingcenter_t_inquiry sti on ctg.inquiry_id = sti.id\n" +
                    "        left join sourcingcenter.i_sourcingcenter_t_inquiry_goods sig on sig.inquiry_id=sti.id where 1 = 1");
            Map<String, Object> parameter = new HashMap<>();
            sql.append(" and (sti.id = (:inquiryId)) and sig.sku = (:sku) and sig.area = (:area) group by ctg.id");
            parameter.put("inquiryId", inquiry.getId());
            parameter.put("sku", inquiryGoods.getSku());
            parameter.put("area", inquiryGoods.getArea());
//            parameter.put("ids", Optional.ofNullable(inquiryGoodsDto.getInquiryGoodsIdList().stream().map(e->"\'" + e + "\'").collect(Collectors.joining(","))).orElse(""));
            log.info("###查询inquiryId::{}", parameter.get("inquiryId").toString());
            List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql.toString(), parameter);
            if (CollectionUtils.isEmpty(resultList)) {
                continue;
            }
            List<String> bizObjectIds = resultList.stream().map(e -> e.get("id").toString()).collect(Collectors.toList());
            log.info("定标流程bizObjectIds信息::{}", JSON.toJSONString(bizObjectIds));
            StringBuffer sqlFlow = new StringBuffer("SELECT * \n" +
                    "        from commoditymaterials.biz_workflow_instance\n" +
                    "        where 1 = 1");
            Map<String, Object> parameterFlow = new HashMap<>();
            sqlFlow.append(" and (bizObjectId in (:bizObjectIds))");
            parameterFlow.put("bizObjectIds", bizObjectIds);
//        parameter.put("bizObjectIds", Optional.ofNullable(bizObjectIds.stream().map(e->"\'" + e + "\'").collect(Collectors.joining(","))).orElse(""));
            List<Map<String, Object>> resultFlowList = jdbcTemplate.queryForList(sqlFlow.toString(), parameterFlow);
            log.info("------------------------resultFlowList：{}------------------------", JSONObject.toJSONString(resultFlowList));
            if (CollectionUtils.isEmpty(resultFlowList)) {
                continue;
            }
            //待关闭询价商品
            dataMap = Maps.newHashMap();
            dataMap.put("id", resultList.get(0).get("inquiryGoodsId"));
            dataMap.put("inquiry_goods_status", InquiryStatusEnum.INQUIRY_GOODS_5_CLOSE.getCode());
            data.add(dataMap);
        }
        // 更新询价商品数据
        if (CollectionUtils.isEmpty(data)) {
            return;
        }
        log.info("-----------------------更新询价商品数据：{}------------------------", JSONObject.toJSONString(data));
        SingleResponse<BO> result = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY_GOODS, data);
        log.info("-----------------------更新询价商品数据结果result：{}------------------------", JSONObject.toJSONString(result));
    }


    /**
     * 获取待申请询价单列表
     *
     * @param askForInquiryDto 查询条件
     * @return 查询结果
     */
    @Path("askForInquiryList")
    @POST
    @Operation(summary = "获取待申请询价单列表", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> askForInquiryList(@Parameter AskForInquiryDto askForInquiryDto) {
        BOList boList = new BOList();
        // 获取表名
        Map<String, Object> parameter = Maps.newHashMap();
        // 拼接sql
        StringBuilder totalSql = new StringBuilder();// 获取总数
        StringBuilder querySql = new StringBuilder();// 查询条件
        StringBuilder listSql = new StringBuilder();// 获取结果
        totalSql.append("select count(*) as count from (\n");
        totalSql.append("select distinct i.* from \n");
        querySql.append(inquiryName).append(" as i\n");
        querySql.append("left join\n");
        querySql.append(inquiryGoodsName).append(" as ig\n");
        querySql.append("on ig.inquiry_id = i.id\n");
        querySql.append("where 1 = 1\n");
        querySql.append("and i.deleted = :deleted\n");
        parameter.put("deleted", 0);
        querySql.append("and ig.inquiry_goods_status = :status\n");
        parameter.put("status", "0");
        querySql.append("and ig.deleted = :deleted\n");
        // 询价单id
        if (!StringUtils.isEmpty(askForInquiryDto.getId())) {
            String[] ids = askForInquiryDto.getId().split(";");
            querySql.append("and i.id in (:id)\n");
            parameter.put("id", Arrays.asList(ids));
        }
        // 询价单标题
        if (!StringUtils.isEmpty(askForInquiryDto.getName())) {
            querySql.append("and i.name like :name\n");
            parameter.put("name", "%".concat(askForInquiryDto.getName()).concat("%"));
        }
        // 询价人
        if (!StringUtils.isEmpty(askForInquiryDto.getMember_name())) {
            querySql.append("and i.member_name like :memberName\n");
            parameter.put("memberName", "%".concat(askForInquiryDto.getMember_name()).concat("%"));
        }
        // 询价创建时间
        if (!CollectionUtils.isEmpty(askForInquiryDto.getCreatedTime())) {
            querySql.append("and i.createdTime BETWEEN :createdStartTime and :createdEndTime\n");
            parameter.put("createdStartTime", askForInquiryDto.getCreatedTime().get(0));
            parameter.put("createdEndTime", askForInquiryDto.getCreatedTime().get(1));
        }
        // 拼接权限sql
        SqlWithParams inquiryPermissionSql = PermissionUtils.permissionSql(ModelConst.T_INQUIRY, ModelConst.T_INQUIRY, "i");
        log.info("------------------------询价单权限sql：{}------------------------", JSONObject.toJSONString(inquiryPermissionSql));
        if (inquiryPermissionSql != null && !StringUtils.isEmpty(inquiryPermissionSql.getSql())) {
            querySql.append("and ").append(inquiryPermissionSql.getSql()).append("\n");
            parameter.putAll(inquiryPermissionSql.getParams());
        }
        SqlWithParams inquiryGoodsPermissionSql = PermissionUtils.permissionSql(ModelConst.T_INQUIRY, ModelConst.T_INQUIRY_GOODS, "ig");
        log.info("------------------------询价商品权限sql：{}------------------------", JSONObject.toJSONString(inquiryGoodsPermissionSql));
        if (inquiryGoodsPermissionSql != null && !StringUtils.isEmpty(inquiryGoodsPermissionSql.getSql())) {
            querySql.append("and ").append(inquiryGoodsPermissionSql.getSql()).append("\n");
            parameter.putAll(inquiryGoodsPermissionSql.getParams());
        }
        totalSql.append(querySql);
        totalSql.append(") as inq");
        log.info("totalSql = {}, parameters = {}", totalSql, JSONObject.toJSONString(parameter));
        // 获取列表总数
        Integer count;
        try {
            count = jdbcTemplate.queryForObject(totalSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            count = 0;
            e.printStackTrace();
        }
        if (count == null || count == 0) {
            boList.setSchemaCode(ModelConst.T_INQUIRY);
            boList.setTotal(0);
            return SingleResponse.of(boList);
        }
        listSql.append("select distinct i.* from \n");
        listSql.append(querySql);
        listSql.append("order by createdTime desc");
        String limit = String.format(" limit %s,%s", (askForInquiryDto.getPageIndex() - 1) * askForInquiryDto.getPageSize(), askForInquiryDto.getPageSize());
        listSql.append(limit);
        log.info("listSql = {}, parameters = {}", listSql, JSONObject.toJSONString(parameter));
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), parameter);
        log.info("-------------------待申请询价单列表数据：{}-------------------", JSONObject.toJSONString(result));
        // 对结果进行格式化
        BoResultFormat.resultFormat(result, ModelConst.T_INQUIRY, true);
        log.info("-------------------待申请询价单格式化后列表数据：{}-------------------", JSONObject.toJSONString(result));
        boList.setData(result);
        boList.setSchemaCode(ModelConst.T_INQUIRY);
        boList.setTotal(count);
        return SingleResponse.of(boList);
    }

    /**
     * 提前截止询价
     *
     * @param inquiryGoodsDto 请求参数
     * @return 响应结果
     */
    @Path("endInquiryInAdvance")
    @POST
    @Operation(summary = "提前截止询价", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> endInquiryInAdvance(@Parameter InquiryGoodsDto inquiryGoodsDto) {
        List<Map<String, Object>> data = new ArrayList<>();
        List<Map<String, Object>> childData = new ArrayList<>();
        Map<String, Object> dataMap;
        Map<String, Object> childMap;
        // 询价单id去重
        List<String> inquiryIdList = inquiryGoodsDto.getInquiryIdList().stream().distinct().collect(Collectors.toList());

        for (String inquiryId : inquiryIdList) {
            dataMap = Maps.newHashMap();
            dataMap.put("id", inquiryId);
            dataMap.put("expire", new Date());
            // 获取询价商品信息
            SingleResponse<BOList> inquiryGoodsList = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, ConfigConstant.INQUIRY_ID, inquiryId);
            for (int i = 0; i < inquiryGoodsList.getData().getTotal(); i++) {
                childMap = Maps.newHashMap();
                childMap.put("id", inquiryGoodsList.getData().getData().get(i).get("id"));
                childMap.put("inquiry_goods_status", InquiryStatusEnum.INQUIRY_GOODS_4_END.getCode());
                childMap.put("closing_reason", inquiryGoodsDto.getClosingReason());
                childData.add(childMap);
            }
            data.add(dataMap);
        }
        // 更新询价单数据
        SingleResponse<BO> result = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY, data);
        log.info("------------------------提前截止询价更新询价单成功，更新后数据：{}------------------------", JSONObject.toJSONString(result));

        // 更新询价商品数据
        SingleResponse<BO> childResult = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY_GOODS, childData);
        log.info("------------------------提前截止询价更新询价商品成功，更新后数据：{}------------------------", JSONObject.toJSONString(childResult));
        return result;
    }

    /**
     * 关闭询价商品
     *
     * @param inquiryGoodsDto 请求参数
     * @return 响应结果
     */
    @Path("closeInquiryGoods")
    @POST
    @Operation(summary = "关闭询价商品", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> closeInquiryGoods(@Parameter InquiryGoodsDto inquiryGoodsDto) {
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> dataMap;

        for (String inquiryGoodsId : inquiryGoodsDto.getInquiryGoodsIdList()) {
            dataMap = Maps.newHashMap();
            dataMap.put("id", inquiryGoodsId);
            dataMap.put("inquiry_goods_status", InquiryStatusEnum.INQUIRY_GOODS_5_CLOSE.getCode());
            data.add(dataMap);
        }
        // 更新询价商品数据
        log.info("-----------------------更新询价商品数据：{}------------------------", JSONObject.toJSONString(data));
        SingleResponse<BO> result = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY_GOODS, data);
        //新建线程并执行结束相关流程
        new Thread(() -> {
            log.info("异步调用发结束相关流程::{}", JSON.toJSONString(result));
            StringBuffer sql = new StringBuffer("SELECT ctg.*,sti.id as inquiryId,sig.id as inquiryGoodsId \n" +
                    "        from commoditymaterials.i_commoditymaterials_t_goods_purchase ctg left join sourcingcenter.i_sourcingcenter_t_inquiry sti on ctg.inquiry_id = sti.id\n" +
                    "        left join sourcingcenter.i_sourcingcenter_t_inquiry_goods sig on sig.inquiry_id=sti.id where 1 = 1");
            Map<String, Object> parameter = new HashMap<>();
            sql.append(" and (sig.id in (:ids)) group by ctg.id");
            parameter.put("ids", inquiryGoodsDto.getInquiryGoodsIdList());
//            parameter.put("ids", Optional.ofNullable(inquiryGoodsDto.getInquiryGoodsIdList().stream().map(e->"\'" + e + "\'").collect(Collectors.joining(","))).orElse(""));
            log.info("###查询ids::{}", parameter.get("ids").toString());
            List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql.toString(), parameter);
            log.info("###查询resultList::{}", JSON.toJSONString(resultList));
            if (!CollectionUtils.isEmpty(resultList)) {
                List<String> bizObjectIds = resultList.stream().map(e -> e.get("id").toString()).collect(Collectors.toList());
                String url = HttpClients.getUrl(AppConst.COMMODITYMATERIALS, ServiceUrlConst.APPROVAL_BATCH_DELETE_URL);
                Map<String, Object> fileParam = Maps.newHashMap();
                fileParam.put("bizObjectIds", bizObjectIds);
                String execute = HttpClients.execute(url, fileParam);
                log.info("返回结果::{}", JSON.toJSONString(execute));
            }
        }).start();
        log.info("------------------------更新询价商品成功，更新后数据：{}------------------------", JSONObject.toJSONString(result));
        return result;
    }

    /**
     * 需求转询价
     *
     * @param demandPoolDto 请求参数
     * @return 响应结果
     */
    @Path("demandToInquiry")
    @POST
    @Operation(summary = "需求转询价", tags = CUSTOM_SERVICE)
    public SingleResponse<Inquiry> demandToInquiry(@Parameter DemandPoolDto demandPoolDto) {
        List<String> demandPoolIdList = demandPoolDto.getDemandPoolIdList().stream().
                sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        // 获取需求商品信息
        List<String> demandGoodsIdList = getDemandGoodsId(demandPoolDto.getDemandPoolIdList());
        log.info("------------------------通过需求池id获取需求商品id列表：{}------------------------", JSONObject.toJSONString(demandGoodsIdList));
        Inquiry inquiry = getDemandData(demandPoolIdList.get(0), demandGoodsIdList);
        log.info("------------------------需求转询价时询价单信息：{}------------------------", JSONObject.toJSONString(inquiry));
        return SingleResponse.of(inquiry);
    }

    /**
     * 需求商品转询价
     *
     * @param demandPoolDto 请求参数
     * @return 响应结果
     */
    @Path("demandGoodsToInquiry")
    @POST
    @Operation(summary = "需求商品转询价", tags = CUSTOM_SERVICE)
    public SingleResponse<Inquiry> demandGoodsToInquiry(@Parameter DemandPoolDto demandPoolDto) {
        // 根据需求商品id获取需求池id
        List<String> demandPoolIdList = getDemandPoolId(demandPoolDto.getDemandGoodsIdList()).stream().distinct()
                .sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        log.info("------------------------通过需求商品id获取需求池id列表：{}------------------------", JSONObject.toJSONString(demandPoolIdList));

        Inquiry inquiry = getDemandData(demandPoolIdList.get(0), demandPoolDto.getDemandGoodsIdList());
        log.info("------------------------需求商品转询价时询价单信息：{}------------------------", JSONObject.toJSONString(inquiry));
        return SingleResponse.of(inquiry);
    }

    /**
     * 需求转询价后更新需求商品状态
     *
     * @param demandPoolDto 请求参数
     * @return 响应结果
     */
    @Path("updateDemandGoodsStatus")
    @POST
    @Operation(summary = "需求转询价后更新需求商品状态", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateDemandGoodsStatus(@Parameter DemandPoolDto demandPoolDto) {
        // 获取需求池信息
        List<String> demandPoolIdList = getDemandPoolId(demandPoolDto.getDemandGoodsIdList()).stream().distinct()
                .sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        demandPoolDto.setDemandPoolIdList(demandPoolIdList);

        String url = HttpClients.getUrl(AppConst.DEMAND_POOL, ServiceUrlConst.UPDATE_STATUS_BY_INQUIRY_URL);
        Map<String, Object> param = Maps.newHashMap();
        param.put("demandPoolIdList", demandPoolDto.getDemandPoolIdList());
        param.put("demandGoodsIdList", demandPoolDto.getDemandGoodsIdList());

        String result = HttpClients.execute(url, param);
        SingleResponse<BO> response = TypeReferenceUtils.readValueToSingleResponse(result);
        log.info("------------------------需求转询价后更新需求商品状态结果：{}------------------------", JSONObject.toJSONString(response));
        return response;
    }

    /**
     * 再次询价
     *
     * @param inquiryGoodsDto 请求参数
     * @return 响应结果
     */
    @Path("inquiryAgain")
    @POST
    @Operation(summary = "再次询价", tags = CUSTOM_SERVICE)
    public SingleResponse<Inquiry> inquiryAgain(@Parameter InquiryGoodsDto inquiryGoodsDto) {
        List<String> inquiryIdList = getInquiryId(inquiryGoodsDto.getInquiryGoodsIdList()).stream().distinct()
                .sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        log.info("------------------------根据询价商品id获取询价单id列表：{}------------------------", JSONObject.toJSONString(inquiryIdList));

        inquiryGoodsDto.setInquiryIdList(inquiryIdList);
        Inquiry inquiry = getInquiryData(inquiryIdList.get(0), inquiryGoodsDto.getInquiryGoodsIdList());
        log.info("------------------------再次询价后新的询价单信息：{}------------------------", JSONObject.toJSONString(SingleResponse.of(inquiry)));
        return SingleResponse.of(inquiry);
    }

    /**
     * 批量修改成本中心
     *
     * @param dto 请求参数
     * @return 响应结果
     */
    @Path("updateCostCenterName")
    @POST
    @Operation(summary = "批量修改成本中心", tags = CUSTOM_SERVICE)
    public SingleResponse<?> updateCostCenterName(InquiryDto dto) {
        log.info("==========dto={}", JSON.toJSON(dto));
        if (dto.getInquiryIdList().isEmpty() || dto.getCostCenterName() == null) {
            return SingleResponse.error("-1", "参数不合法");
        }
        StringBuilder sql = new StringBuilder("update ").append(getTableName(ModelConst.T_INQUIRY)).append(" set ");
        sql.append("cost_center_name=:costCenterName where id in (:id)");
        MapBuilder<String, Object> mapBuilder = MapUtil.builder("id", dto.getInquiryIdList());
        mapBuilder.put("costCenterName", dto.getCostCenterName());
        log.info("==========sql={},map={}", sql, mapBuilder.build());

        int update = jdbcTemplate.update(sql.toString(), mapBuilder.build());
        log.info("=============update={}", update);
        return SingleResponse.buildSuccess();
    }

    /**
     * 获取报价中列表
     *
     * @param inQuotationDto 请求参数
     * @return 响应结果
     */
    @Path("inQuotationList")
    @POST
    @Operation(summary = "获取报价中列表", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> inQuotationList(@Parameter InQuotationDto inQuotationDto) {
        BOList boList = new BOList();
        // 获取表名
        Map<String, Object> parameter = Maps.newHashMap();
        // 拼接sql
        StringBuilder totalSql = new StringBuilder();// 获取总数
        StringBuilder querySql = new StringBuilder();// 查询条件
        StringBuilder listSql = new StringBuilder();// 获取结果
        totalSql.append("select count(*) as count from \n");
        querySql.append(inquiryGoodsName).append("\n");
        querySql.append("where 1 = 1\n");
        querySql.append("and inquiry_goods_status = :status\n");
        parameter.put("status", "3");
        querySql.append("and deleted = :deleted\n");
        parameter.put("deleted", 0);
        querySql.append("and expire > :expire\n");
        parameter.put("expire", new Date());
        // 商品编号
        if (!StringUtils.isEmpty(inQuotationDto.getId())) {
            String[] ids = inQuotationDto.getId().split(";");
            querySql.append("and id in (:id)\n");
            parameter.put("id", Arrays.asList(ids));
        }
        // 询价单号
        if (!StringUtils.isEmpty(inQuotationDto.getInquiry_id())) {
            String[] ids = inQuotationDto.getInquiry_id().split(";");
            querySql.append("and inquiry_id in (:inquiry_id)\n");
            parameter.put("inquiry_id", Arrays.asList(ids));

        }
        // 询价单标题
        if (!StringUtils.isEmpty(inQuotationDto.getInquiry_name())) {
            querySql.append("and inquiry_name like :inquiry_name\n");
            parameter.put("inquiry_name", "%".concat(inQuotationDto.getInquiry_name()).concat("%"));
        }
        // 询价人
        if (!StringUtils.isEmpty(inQuotationDto.getMember_name())) {
            querySql.append("and member_name like :member_name\n");
            parameter.put("member_name", "%".concat(inQuotationDto.getMember_name()).concat("%"));
        }
        // 客户料号
        if (!StringUtils.isEmpty(inQuotationDto.getSku())) {
            querySql.append("and sku like :sku\n");
            parameter.put("sku", "%".concat(inQuotationDto.getSku()).concat("%"));
        }
        // 询价商品名
        if (!StringUtils.isEmpty(inQuotationDto.getName())) {
            querySql.append("and name like :name\n");
            parameter.put("name", "%".concat(inQuotationDto.getName()).concat("%"));
        }
        // 品牌
        if (!StringUtils.isEmpty(inQuotationDto.getBrand())) {
            querySql.append("and brand like :brand\n");
            parameter.put("brand", "%".concat(inQuotationDto.getBrand()).concat("%"));
        }
        // 型号
        if (!StringUtils.isEmpty(inQuotationDto.getModel())) {
            querySql.append("and model like :model\n");
            parameter.put("model", "%".concat(inQuotationDto.getModel()).concat("%"));
        }
        // 询价商品创建时间
        if (!CollectionUtils.isEmpty(inQuotationDto.getCreatedTime())) {
            querySql.append("and createdTime BETWEEN :createdStartTime and :createdEndTime\n");
            parameter.put("createdStartTime", inQuotationDto.getCreatedTime().get(0));
            parameter.put("createdEndTime", inQuotationDto.getCreatedTime().get(1));
        }
        // 分类
        if (!StringUtils.isEmpty(inQuotationDto.getCategory_id())) {
            querySql.append("and category_id = :category_id\n");
            parameter.put("category_id", inQuotationDto.getCategory_id());
        }
        // 拼接权限sql
        SqlWithParams inquiryGoodsPermissionSql = PermissionUtils.permissionSql(ModelConst.T_INQUIRY, ModelConst.T_INQUIRY_GOODS, null);
        log.info("------------------------询价商品权限sql：{}------------------------", JSONObject.toJSONString(inquiryGoodsPermissionSql));
        if (inquiryGoodsPermissionSql != null && !StringUtils.isEmpty(inquiryGoodsPermissionSql.getSql())) {
            querySql.append("and ").append(inquiryGoodsPermissionSql.getSql()).append("\n");
            parameter.putAll(inquiryGoodsPermissionSql.getParams());
        }
        totalSql.append(querySql);
        log.info("totalSql = {}, parameters = {}", totalSql, JSONObject.toJSONString(parameter));
        // 获取列表总数
        Integer count;
        try {
            count = jdbcTemplate.queryForObject(totalSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
            count = 0;
        }
        if (count == null || count == 0) {
            boList.setSchemaCode(ModelConst.T_INQUIRY_GOODS);
            boList.setTotal(0);
            return SingleResponse.of(boList);
        }
        listSql.append("select * from \n");
        listSql.append(querySql);
        listSql.append("order by createdTime desc");
        String limit = String.format(" limit %s,%s", (inQuotationDto.getPageIndex() - 1) * inQuotationDto.getPageSize(), inQuotationDto.getPageSize());
        listSql.append(limit);
        log.info("listSql = {}, parameters = {}", listSql, JSONObject.toJSONString(parameter));
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), parameter);
        log.info("--------------------报价中列表数据：{}--------------------", JSONObject.toJSONString(result));
        // 对结果进行格式化
        BoResultFormat.resultFormat(result, ModelConst.T_INQUIRY_GOODS, true);
        boList.setData(result);
        boList.setSchemaCode(ModelConst.T_INQUIRY_GOODS);
        boList.setTotal(count);
        return SingleResponse.of(boList);
    }

    /**
     * 一键澄清/批量澄清
     *
     * @param clarifyDtoList 澄清内容
     * @return 响应结果
     */
    @Path("batchClarify")
    @POST
    @Operation(summary = "一键澄清/批量澄清", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> batchClarify(@Parameter List<InquiryGoodsClarifyDto> clarifyDtoList) {
        Assert.notEmpty(clarifyDtoList, "参数不能为空");
        Assert.notBlank(clarifyDtoList.get(0).getClarifyTips(), "询价商品id不能为空");
        Assert.notBlank(clarifyDtoList.get(0).getClarifyTips(), "澄清内容不能为空");

        List<Map<String, Object>> clarifyData = new ArrayList<>();
        Map<String, Object> clarifyMap;
        SingleResponse<BOList> inquiryGoods;
        for (InquiryGoodsClarifyDto clarifyDto : clarifyDtoList) {
            clarifyMap = Maps.newHashMap();
            inquiryGoods = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, "id", clarifyDto.getInquiryGoodsId());
            if (inquiryGoods.getData().getTotal() == 0) {
                throw new BizException("询价商品" + clarifyDto.getInquiryGoodsId() + "不存在！");
            }
            log.info("------------------------通过询价商品id获取询价商品信息：{}------------------------", JSONObject.toJSONString(inquiryGoods));
            String clarifyStatus = String.valueOf(inquiryGoods.getData().getData().get(0).get("clarify_status"));

            clarifyStatus = buildClarifyMap(clarifyMap, clarifyDto, clarifyStatus);
            clarifyData.add(clarifyMap);

            // 更新询价单澄清状态和澄清数量
            clarify(inquiryGoods.getData().getData().get(0), clarifyStatus);
        }
        // 新增澄清记录
        SingleResponse<BO> result = BoServiceUtils.createBo(ModelConst.T_INQUIRY_GOODS_CLARIFY, clarifyData);
        log.info("------------------------创建澄清记录成功，返回结果：{}------------------------", JSONObject.toJSONString(result));
        return result;
    }

    /**
     * 询价商品澄清
     *
     * @param clarifyDto 澄清内容
     * @return 响应结果
     */
    @Path("updateClarifyTips")
    @POST
    @Operation(summary = "询价商品澄清", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateClarifyTips(@Parameter InquiryGoodsClarifyDto clarifyDto) {
        Assert.notBlank(clarifyDto.getInquiryGoodsId(), "询价商品id不能为空");
        Assert.notBlank(clarifyDto.getClarifyTips(), "澄清内容不能为空");

        List<Map<String, Object>> clarifyData = new ArrayList<>();
        Map<String, Object> clarifyMap = Maps.newHashMap();
        SingleResponse<BOList> inquiryGoods = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, "id", clarifyDto.getInquiryGoodsId());
        if (inquiryGoods.getData().getTotal() == 0) {
            throw new BizException("询价商品" + clarifyDto.getInquiryGoodsId() + "不存在！");
        }
        log.info("------------------------通过询价商品id获取询价商品信息：{}------------------------", JSONObject.toJSONString(inquiryGoods));

        String clarifyStatus = String.valueOf(inquiryGoods.getData().getData().get(0).get("clarify_status"));

        clarifyStatus = buildClarifyMap(clarifyMap, clarifyDto, clarifyStatus);

        clarifyData.add(clarifyMap);
        // 新增澄清记录
        SingleResponse<BO> result = BoServiceUtils.createBo(ModelConst.T_INQUIRY_GOODS_CLARIFY, clarifyData);
        log.info("------------------------创建澄清记录成功，返回结果：{}------------------------", JSONObject.toJSONString(result));

        // 更新询价单澄清状态和澄清数量
        clarify(inquiryGoods.getData().getData().get(0), clarifyStatus);
        return result;
    }

    /**
     * 物料维护
     *
     * @param goodsPurchaseDto 请求参数
     * @return 响应结果
     */
    @Path("updateSKU")
    @POST
    @Operation(summary = "物料维护", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateSKU(@Parameter GoodsPurchaseDto goodsPurchaseDto) {
        if (StringUtils.isEmpty(goodsPurchaseDto.getQuotationId())) {
            return SingleResponse.error("-1", "报价商品id不能为空");
        }
        SingleResponse<BOList> quotationGoods = BoServiceUtils.findListBySimple(ModelConst.T_QUOTATION_GOODS, "id", goodsPurchaseDto.getQuotationId());
        if (quotationGoods.getData().getTotal() == 0) {
            return SingleResponse.error("-2", "报价商品不存在，客户料号无法维护");
        }
        String inquiryGoodsId = String.valueOf(quotationGoods.getData().getData().get(0).get("inquiry_goods_id"));
        SingleResponse<BOList> inquiryGoods = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, "id", inquiryGoodsId);
        if (inquiryGoods.getData().getTotal() == 0) {
            return SingleResponse.error("-3", "根据报价商品没有查询到对应的询价商品，客户物料号无法维护");
        }
        // 修改报价商品中的询价商品料号
        Map<String, Object> quotationGoodsMap = Maps.newHashMap();
        quotationGoodsMap.put("id", goodsPurchaseDto.getQuotationId());
        quotationGoodsMap.put("inquiry_sku", goodsPurchaseDto.getSku());
        SingleResponse<BO> quotationGoodsResult = BoServiceUtils.updateMainBo(ModelConst.T_QUOTATION_GOODS, quotationGoodsMap);
        log.info("------------------------更新报价商品物料号成功，更新后结果：{}------------------------", JSONObject.toJSONString(quotationGoodsResult));
        if (!quotationGoodsResult.isSuccess()) {
            return SingleResponse.error("-4", "客户物料号维护失败，请稍后再试");
        }
        // 修改询价商品中的客户料号
        Map<String, Object> inquiryGoodsMap = Maps.newHashMap();
        inquiryGoodsMap.put("id", inquiryGoodsId);
        inquiryGoodsMap.put("sku", goodsPurchaseDto.getSku());
        SingleResponse<BO> inquiryGoodsResult = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY_GOODS, inquiryGoodsMap);
        log.info("------------------------更新询价商品物料号成功，更新后结果：{}------------------------", JSONObject.toJSONString(inquiryGoodsResult));
        return inquiryGoodsResult;
    }

    /**
     * 我的核价-核价列表
     *
     * @param listPricingDto 请求参数
     * @return 响应结果
     */
    @Path("listPricing")
    @POST
    @Operation(summary = "我的核价-核价列表", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> listPricing(@Parameter ListPricingDto listPricingDto) {
        BOList boList = new BOList();
        // 获取表名
        String demandPoolName = "i_demandpool_t_demand_pool";
        String demandGoodsName = "i_demandpool_t_demand_goods";
        Map<String, Object> parameter = Maps.newHashMap();
        // 拼接sql
        StringBuilder totalSql = new StringBuilder();// 获取总数
        StringBuilder querySql = new StringBuilder();// 查询条件
        StringBuilder listSql = new StringBuilder();// 获取结果
        totalSql.append("select count(*) as count from( \n");
        totalSql.append("select i.* from \n");
        querySql.append(inquiryName).append(" as i \n");
        querySql.append("INNER JOIN ").append(inquiryGoodsName).append(" ig ON i.id = ig.inquiry_id AND ( ig.deleted = 0 )\n");
        querySql.append("INNER JOIN ").append(quotationGoodsName).append(" qg ON ig.id = qg.inquiry_goods_id AND ( qg.deleted = 0 AND qg.quotation_goods_status > 2 )\n");
        querySql.append("LEFT OUTER JOIN demandpool.").append(demandGoodsName).append(" dg ON ig.demand_goods_id = dg.id\n");
        querySql.append("LEFT OUTER JOIN demandpool.").append(demandPoolName).append(" dp ON dg.demand_pool_id = dp.id\n");
        querySql.append("where ig.inquiry_goods_status IN (:inquiryGoodsStatus)\n");
        parameter.put("inquiryGoodsStatus", Arrays.asList(InquiryStatusEnum.INQUIRY_GOODS_3_QUOTING.getCode(), InquiryStatusEnum.INQUIRY_GOODS_4_END.getCode()));
        querySql.append("and (EXISTS (SELECT qg2.inquiry_goods_id FROM ").append(quotationGoodsName).append(" qg2 WHERE qg.quotation_goods_status IN (:quotationGoodsStatus) AND qg.deleted = 0 AND ig.ID = qg.inquiry_goods_id))\n");
        parameter.put("quotationGoodsStatus", Arrays.asList(QuotationStatusEnum.QUOTATION_3_QUOTED.getCode(), QuotationStatusEnum.QUOTATION_4_APPROVE_BACK.getCode()));
        querySql.append("AND qg.picketage = 0\n");
        querySql.append("AND (ig.picketaged = 0 OR ig.picketaged IS NULL )\n");
        querySql.append("AND ig.deleted = 0\n");
        querySql.append("AND ig.inquiry_goods_status IN (:inquiryGoodsStatus)\n");
        querySql.append("AND i.deleted = 0\n");
        // 询价单号
        if (!StringUtils.isEmpty(listPricingDto.getId())) {
            String[] ids = listPricingDto.getId().split(";");
            querySql.append("and i.id in (:id)\n");
            parameter.put("id", Arrays.asList(ids));
        }
        // 询价标题
        if (!StringUtils.isEmpty(listPricingDto.getName())) {
            querySql.append("and i.name like :name\n");
            parameter.put("name", "%".concat(listPricingDto.getName()).concat("%"));
        }
        // 询价人
        if (!StringUtils.isEmpty(listPricingDto.getMember_name())) {
            querySql.append("and i.member_name like :memberName\n");
            parameter.put("memberName", "%".concat(listPricingDto.getMember_name()).concat("%"));
        }
        // 询价开始日期
        if (!CollectionUtils.isEmpty(listPricingDto.getCreatedTime())) {
            querySql.append("and i.createdTime BETWEEN :createdStartTime and :createdEndTime\n");
            parameter.put("createdStartTime", listPricingDto.getCreatedTime().get(0));
            parameter.put("createdEndTime", listPricingDto.getCreatedTime().get(1));
        }
        // 询价截止日期
        if (!CollectionUtils.isEmpty(listPricingDto.getExpire())) {
            querySql.append("and i.expire BETWEEN :expireStartTime and :expireEndTime\n");
            parameter.put("expireStartTime", listPricingDto.getExpire().get(0));
            parameter.put("expireEndTime", listPricingDto.getExpire().get(1));
        }
        // 拼接权限sql
        SqlWithParams inquiryPermissionSql = PermissionUtils.permissionSql(ModelConst.T_INQUIRY, ModelConst.T_INQUIRY, "i");
        log.info("------------------------询价单权限sql：{}------------------------", JSONObject.toJSONString(inquiryPermissionSql));
        if (inquiryPermissionSql != null && !StringUtils.isEmpty(inquiryPermissionSql.getSql())) {
            querySql.append("and ").append(inquiryPermissionSql.getSql()).append("\n");
            parameter.putAll(inquiryPermissionSql.getParams());
        }
        querySql.append("GROUP BY i.id\n");
        totalSql.append(querySql);
        totalSql.append(") as r");
        log.info("totalSql = {}, parameters = {}", totalSql, JSONObject.toJSONString(parameter));
        // 获取列表总数
        Integer count;
        try {
            count = jdbcTemplate.queryForObject(totalSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
            count = 0;
        }
        if (count == null || count == 0) {
            boList.setSchemaCode(ModelConst.T_INQUIRY);
            boList.setTotal(0);
            return SingleResponse.of(boList);
        }
        listSql.append("select i.* from \n");
        listSql.append(querySql);
        listSql.append("order by i.createdTime desc");
        String limit = String.format(" limit %s,%s", (listPricingDto.getPageIndex() - 1) * listPricingDto.getPageSize(), listPricingDto.getPageSize());
        listSql.append(limit);
        log.info("listSql = {}, parameters = {}", listSql, JSONObject.toJSONString(parameter));
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), parameter);
        log.info("------------------------我的核价-核价列表：{}------------------------", JSONObject.toJSONString(result));
        // 对结果进行格式化
        BoResultFormat.resultFormat(result, ModelConst.T_INQUIRY, true);
        boList.setData(result);
        boList.setSchemaCode(ModelConst.T_INQUIRY);
        boList.setTotal(count);
        return SingleResponse.of(boList);
    }

    /**
     * 我的核价-核价历史列表
     *
     * @param listEndInquiryDto 请求参数
     * @return 响应结果
     */
    @Path("listEndInquiry")
    @POST
    @Operation(summary = "我的核价-核价历史列表", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> listEndInquiry(@Parameter ListEndInquiryDto listEndInquiryDto) {
        BOList boList = new BOList();
        // 获取表名
        Map<String, Object> parameter = Maps.newHashMap();
        // 拼接sql
        StringBuilder totalSql = new StringBuilder();// 获取总数
        StringBuilder querySql = new StringBuilder();// 查询条件
        StringBuilder listSql = new StringBuilder();// 获取结果
        totalSql.append("select count(*) as count from( \n");
        totalSql.append("select i.* from \n");
        querySql.append(inquiryName).append(" as i \n");
        querySql.append("INNER JOIN ").append(inquiryGoodsName).append(" ig ON i.id = ig.inquiry_id AND ( ig.deleted = 0 )\n");
        querySql.append("where ig.deleted = 0\n");
        querySql.append("AND ig.inquiry_goods_status IN (:inquiryGoodsStatus)\n");
        parameter.put("inquiryGoodsStatus", Arrays.asList(InquiryStatusEnum.INQUIRY_GOODS_4_END.getCode(), InquiryStatusEnum.INQUIRY_GOODS_5_CLOSE.getCode()));
        querySql.append("AND i.deleted = 0\n");
        querySql.append("AND ig.picketaged = 1\n");
        // 询价单号
        if (!StringUtils.isEmpty(listEndInquiryDto.getId())) {
            String[] ids = listEndInquiryDto.getId().split(";");
            querySql.append("and i.id in (:id)\n");
            parameter.put("id", Arrays.asList(ids));
        }
        // 询价标题
        if (!StringUtils.isEmpty(listEndInquiryDto.getName())) {
            querySql.append("and i.name like :name\n");
            parameter.put("name", "%".concat(listEndInquiryDto.getName()).concat("%"));
        }
        // 询价开始日期
        if (!CollectionUtils.isEmpty(listEndInquiryDto.getCreatedTime())) {
            querySql.append("and i.createdTime BETWEEN :createdStartTime and :createdEndTime\n");
            parameter.put("createdStartTime", listEndInquiryDto.getCreatedTime().get(0));
            parameter.put("createdEndTime", listEndInquiryDto.getCreatedTime().get(1));
        }
        // 询价截止日期
        if (!CollectionUtils.isEmpty(listEndInquiryDto.getExpire())) {
            querySql.append("and i.expire BETWEEN :expireStartTime and :expireEndTime\n");
            parameter.put("expireStartTime", listEndInquiryDto.getExpire().get(0));
            parameter.put("expireEndTime", listEndInquiryDto.getExpire().get(1));
        }
        // 拼接权限sql
        SqlWithParams inquiryPermissionSql = PermissionUtils.permissionSql(ModelConst.T_INQUIRY, ModelConst.T_INQUIRY, "i");
        log.info("------------------------询价单权限sql：{}------------------------", JSONObject.toJSONString(inquiryPermissionSql));
        if (inquiryPermissionSql != null && !StringUtils.isEmpty(inquiryPermissionSql.getSql())) {
            querySql.append("and ").append(inquiryPermissionSql.getSql()).append("\n");
            parameter.putAll(inquiryPermissionSql.getParams());
        }
        querySql.append("GROUP BY i.id\n");
        totalSql.append(querySql);
        totalSql.append(") as r");
        log.info("totalSql = {}, parameters = {}", totalSql, JSONObject.toJSONString(parameter));
        // 获取列表总数
        Integer count;
        try {
            count = jdbcTemplate.queryForObject(totalSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
            count = 0;
        }
        if (count == null || count == 0) {
            boList.setSchemaCode(ModelConst.T_INQUIRY);
            boList.setTotal(0);
            return SingleResponse.of(boList);
        }
        listSql.append("select i.* from \n");
        listSql.append(querySql);
        listSql.append("order by i.createdTime desc");
        String limit = String.format(" limit %s,%s", (listEndInquiryDto.getPageIndex() - 1) * listEndInquiryDto.getPageSize(), listEndInquiryDto.getPageSize());
        listSql.append(limit);
        log.info("listSql = {}, parameters = {}", listSql, JSONObject.toJSONString(parameter));
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), parameter);
        // 对结果进行格式化
        BoResultFormat.resultFormat(result, ModelConst.T_INQUIRY, true);
        log.info("------------------------我的核价-核价历史列表：{}------------------------", JSONObject.toJSONString(result));
        boList.setData(result);
        boList.setSchemaCode(ModelConst.T_INQUIRY);
        boList.setTotal(count);
        return SingleResponse.of(boList);
    }

    /**
     * 我的核价-核价商品列表
     *
     * @param inquiryGoodsEntityListDto 请求参数
     * @return 响应结果
     */
    @Path("getInquiryGoodsEntityList")
    @POST
    @Operation(summary = "我的核价-核价商品列表", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> getInquiryGoodsEntityList(@Parameter InquiryGoodsEntityListDto inquiryGoodsEntityListDto) {
        BOList boList = new BOList();
        // 获取表名
        Map<String, Object> parameter = Maps.newHashMap();
        // 拼接sql
        StringBuilder totalSql = new StringBuilder();// 获取总数
        StringBuilder querySql = new StringBuilder();// 查询条件
        StringBuilder listSql = new StringBuilder();// 获取结果
        totalSql.append("select count(*) as count from( \n");
        totalSql.append("select ig.* from \n");
        querySql.append(inquiryGoodsName).append(" ig \n");
        querySql.append("LEFT OUTER JOIN ").append(inquiryName).append(" i ON ig.inquiry_id = i.id\n");
        querySql.append("LEFT OUTER JOIN ").append(quotationGoodsName).append(" qg ON ig.id = qg.inquiry_goods_id AND ( qg.deleted = 0 AND qg.quotation_goods_status > 2 )\n");
        querySql.append("where ig.deleted = 0\n");
        querySql.append("and i.deleted = 0\n");
        querySql.append("and qg.deleted = 0\n");
        querySql.append("and (ig.inquiry_goods_status =3 AND ( i.quote_hermetic_strategy = 0 OR i.expire <= :expire )\n");
//        querySql.append("or ig.inquiry_goods_status =4 AND ( ig.picketaged = 0 OR ig.picketaged IS NULL ))\n");
        querySql.append("or ig.inquiry_goods_status =4 )\n");
        parameter.put("expire", new Date());
        // 商品编号
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getId())) {
            String[] ids = inquiryGoodsEntityListDto.getId().split(";");
            querySql.append("and ig.id in (:id)\n");
            parameter.put("id", Arrays.asList(ids));
        }
        // 询价商品状态。1：询价中 2：已定标
        if ("1".equals(inquiryGoodsEntityListDto.getPicketaged())) {
            querySql.append("and ig.picketaged = 0\n");
        } else if ("2".equals(inquiryGoodsEntityListDto.getPicketaged())) {
            querySql.append("and ig.picketaged = 1\n");
        }
        // 询价单号
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getInquiry_id())) {
            querySql.append("and ig.inquiry_id = :inquiryId\n");
            parameter.put("inquiryId", inquiryGoodsEntityListDto.getInquiry_id());
        }
        // 标题
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getInquiry_name())) {
            querySql.append("and ig.inquiry_name like :inquiryName\n");
            parameter.put("inquiryName", "%".concat(inquiryGoodsEntityListDto.getInquiry_name()).concat("%"));
        }
        // 客户料号
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getSku())) {
            querySql.append("and ig.sku like :sku\n");
            parameter.put("sku", "%".concat(inquiryGoodsEntityListDto.getSku()).concat("%"));
        }
        // 询价开始日期
        if (!CollectionUtils.isEmpty(inquiryGoodsEntityListDto.getCreatedTime())) {
            querySql.append("and ig.createdTime BETWEEN :createdStartTime and :createdEndTime\n");
            parameter.put("createdStartTime", inquiryGoodsEntityListDto.getCreatedTime().get(0));
            parameter.put("createdEndTime", inquiryGoodsEntityListDto.getCreatedTime().get(1));
        }
        // 询价截止日期
        if (!CollectionUtils.isEmpty(inquiryGoodsEntityListDto.getExpire())) {
            querySql.append("and ig.expire BETWEEN :expireStartTime and :expireEndTime\n");
            parameter.put("expireStartTime", inquiryGoodsEntityListDto.getExpire().get(0));
            parameter.put("expireEndTime", inquiryGoodsEntityListDto.getExpire().get(1));
        }
        // 商品名
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getName())) {
            querySql.append("and ig.name like :name\n");
            parameter.put("name", "%".concat(inquiryGoodsEntityListDto.getName()).concat("%"));
        }
        // 品牌
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getBrand())) {
            querySql.append("and ig.brand like :brand\n");
            parameter.put("brand", "%".concat(inquiryGoodsEntityListDto.getBrand()).concat("%"));
        }
        // 商品名
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getModel())) {
            querySql.append("and ig.model like :model\n");
            parameter.put("model", "%".concat(inquiryGoodsEntityListDto.getModel()).concat("%"));
        }
        // 分类
        if (!StringUtils.isEmpty(inquiryGoodsEntityListDto.getPlatform_category_name())) {
            querySql.append("and ig.platform_category_name like :platformCategoryName\n");
            parameter.put("platformCategoryName", "%".concat(inquiryGoodsEntityListDto.getPlatform_category_name()).concat("%"));
        }
        // 拼接权限sql
        SqlWithParams inquiryGoodsPermissionSql = PermissionUtils.permissionSql(ModelConst.T_INQUIRY, ModelConst.T_INQUIRY_GOODS, "ig");
        log.info("------------------------询价商品权限sql：{}------------------------", JSONObject.toJSONString(inquiryGoodsPermissionSql));
        if (inquiryGoodsPermissionSql != null && !StringUtils.isEmpty(inquiryGoodsPermissionSql.getSql())) {
            querySql.append("and ").append(inquiryGoodsPermissionSql.getSql()).append("\n");
            parameter.putAll(inquiryGoodsPermissionSql.getParams());
        }
        querySql.append("GROUP BY ig.id\n");
        totalSql.append(querySql);
        totalSql.append(") as r");
        log.info("totalSql = {}, parameters = {}", totalSql, JSONObject.toJSONString(parameter));
        // 获取列表总数
        Integer count;
        try {
            count = jdbcTemplate.queryForObject(totalSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
            count = 0;
        }
        if (count == null || count == 0) {
            boList.setSchemaCode(ModelConst.T_INQUIRY_GOODS);
            boList.setTotal(0);
            return SingleResponse.of(boList);
        }
        listSql.append("select ig.* from \n");
        listSql.append(querySql);
        listSql.append("order by ig.createdTime desc");
        String limit = String.format(" limit %s,%s", (inquiryGoodsEntityListDto.getPageIndex() - 1) * inquiryGoodsEntityListDto.getPageSize(), inquiryGoodsEntityListDto.getPageSize());
        listSql.append(limit);
        log.info("listSql = {}, parameters = {}", listSql, JSONObject.toJSONString(parameter));
        List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(), parameter);
        // 对结果进行格式化
        BoResultFormat.resultFormat(result, ModelConst.T_INQUIRY_GOODS, true);
        log.info("------------------------我的核价-核价商品列表：{}------------------------", JSONObject.toJSONString(result));
        boList.setData(result);
        boList.setSchemaCode(ModelConst.T_INQUIRY_GOODS);
        boList.setTotal(count);
        return SingleResponse.of(boList);
    }

    /**
     * 获取核价页面数据
     *
     * @param inquiryDto 请求参数
     * @return 响应结果
     */
    @Path("newPricingHistory")
    @POST
    @Operation(summary = "获取核价页面数据", tags = CUSTOM_SERVICE)
    public SingleResponse<InquiryVo> newPricingHistory(@Parameter InquiryDto inquiryDto) {
        if (StringUtils.isEmpty(inquiryDto.getInquiryId())) {
            return SingleResponse.error("-1", "参数不能为空，请检查参数");
        }

        List<InquiryGoodsVo> inquiryGoodsList;
        List<QuotationGoodsVo> quotationGoodsList;
        BOList quotationGoodsResult;
        // 通过询价单号获取询价单信息
        SingleResponse<BOList> inquiryResult = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY, "id", inquiryDto.getInquiryId());
        log.info("------------------------根据询价单id获取询价单信息：{}------------------------", JSONObject.toJSONString(inquiryResult));

        InquiryVo inquiryVo = JSONUtil.toBean(JSONUtil.toJsonStr(inquiryResult.getData().getData().get(0)), InquiryVo.class);
        log.info("------------------------询价单map转vo：{}------------------------", JSONObject.toJSONString(inquiryVo));

        // 获取询价商品信息
        StringBuilder sql = new StringBuilder();
        Map<String, Object> parameter = Maps.newHashMap();
        sql.append("select g.* from\n");
        sql.append(getTableName(ModelConst.T_INQUIRY_GOODS)).append(" g\n");
        sql.append("left join ").append(getTableName(ModelConst.T_QUOTATION_GOODS)).append(" q\n");
        sql.append("on q.inquiry_goods_id=g.id\n");
        sql.append("where g.deleted=0 and q.deleted=0\n");
        sql.append("and g.inquiry_id = :inquiryId\n");
        parameter.put("inquiryId", inquiryDto.getInquiryId());
        sql.append("and q.quotation_goods_status = 0 and q.quotation_goods_status = 7\n");
        sql.append("GROUP BY g.id ORDER BY g.createdTime DESC");
        log.info("sql = {}, parameters = {}", sql, JSONObject.toJSONString(parameter));
        List<Map<String, Object>> inquiryGoodsResult = jdbcTemplate.queryForList(sql.toString(), parameter);
        log.info("------------------------获取询价商品列表数据：{}------------------------", JSONObject.toJSONString(inquiryGoodsResult));

        //如果没有报价，手动结束询价，则用原来的查询
        if (CollectionUtils.isEmpty(inquiryGoodsResult)) {
            inquiryGoodsResult = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, "inquiry_id", inquiryDto.getInquiryId()).getData().getData();
            log.info("------------------------获取询价商品列表数据：{}------------------------", JSONObject.toJSONString(inquiryGoodsResult));
        }
        inquiryGoodsList = JSONUtil.toList(JSONUtil.parseArray(inquiryGoodsResult), InquiryGoodsVo.class);
        inquiryVo.setInquiryGoodsList(inquiryGoodsList);

        String[] columnNames = new String[]{"quotation_goods_status", "inquiry_goods_id", "amount"};
        Operator[] operators = new Operator[]{Operator.IN, Operator.EQ, Operator.IS_NOT_NULL};
        Object[] columnValues = new Object[3];
        columnValues[0] = Arrays.asList(QuotationStatusEnum.QUOTATION_3_QUOTED.getCode(), QuotationStatusEnum.QUOTATION_4_APPROVE_BACK.getCode(),
                QuotationStatusEnum.QUOTATION_5_PICKETED.getCode(), QuotationStatusEnum.QUOTATION_6_CLOSE.getCode());
        columnValues[2] = "";
        // 根据询价商品id获取报价商品信息
        for (InquiryGoodsVo inquiryGoodsVo : inquiryGoodsList) {
            columnValues[1] = inquiryGoodsVo.getId();
            quotationGoodsResult = BoServiceUtils.findListByComplex(ModelConst.T_QUOTATION_GOODS, columnNames, columnValues, operators).getData();
            log.info("------------------------根据询价商品id获取报价商品id：{}------------------------", JSONObject.toJSONString(quotationGoodsResult));
            if (quotationGoodsResult.getTotal() > 0) {
                quotationGoodsList = JSONUtil.toList(JSONUtil.parseArray(quotationGoodsResult.getData()), QuotationGoodsVo.class);
                // 报价商品冗余询价商品状态字段，方便前端处理
                for (QuotationGoodsVo quotationGoodsVo : quotationGoodsList) {
                    quotationGoodsVo.setInquiry_goods_status(inquiryGoodsVo.getInquiry_goods_status());
                }
                inquiryGoodsVo.setQuotationGoodsList(quotationGoodsList);
            }
        }
        return SingleResponse.of(inquiryVo);
    }

    /**
     * 澄清记录
     *
     * @param inquiryGoodsClarifyDto 请求参数
     * @return 响应结果
     */
    @Path("clarifyRecord")
    @POST
    @Operation(summary = "澄清记录", tags = CUSTOM_SERVICE)
    public SingleResponse<List<InquiryGoodsClarifyVo>> clarifyRecord(@Parameter InquiryGoodsClarifyDto inquiryGoodsClarifyDto) {
        if (StringUtils.isEmpty(inquiryGoodsClarifyDto.getInquiryGoodsId())) {
            return SingleResponse.error("-1", "询价商品号不能为空");
        }
        SingleResponse<BOList> inquiryGoodsClarifyResult = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS_CLARIFY, "inquiry_goods_id", inquiryGoodsClarifyDto.getInquiryGoodsId());
        List<InquiryGoodsClarifyVo> inquiryGoodsClarifyList = Lists.newArrayList();
        if (inquiryGoodsClarifyResult.getData().getTotal() > 0) {
            inquiryGoodsClarifyList = JSONUtil.toList(JSONUtil.parseArray(inquiryGoodsClarifyResult.getData().getData()), InquiryGoodsClarifyVo.class);
            JSONArray array;
            for (InquiryGoodsClarifyVo inquiryGoodsClarifyVo : inquiryGoodsClarifyList) {
                array = inquiryGoodsClarifyVo.getAttachment();
                if (array != null && array.size() > 0) {
                    for (int i = 0; i < array.size(); i++) {
                        array.getJSONObject(i).put("url", "/api/file/download?refId=".concat(String.valueOf(array.getJSONObject(i).get("id"))));
                        array.getJSONObject(i).put("uid", String.valueOf(array.getJSONObject(i).get("id")));
                    }
                }
            }
            log.info("------------------------根据询价商品id获取澄清记录列表：{}------------------------", JSONObject.toJSONString(inquiryGoodsClarifyResult));
        }
        return SingleResponse.of(inquiryGoodsClarifyList);
    }

    /**
     * 根据多个询价商品id获取询价商品列表
     *
     * @param inquiryGoodsDto 请求参数
     * @return 响应结果
     */
    @Path("getInquiryGoodsList")
    @POST
    @Operation(summary = "根据多个询价商品id获取询价商品列表", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> getInquiryGoodsList(@Parameter InquiryGoodsDto inquiryGoodsDto) {
        if (inquiryGoodsDto.getInquiryGoodsIdList() == null || inquiryGoodsDto.getInquiryGoodsIdList().isEmpty()) {
            return SingleResponse.error("-1", "询价商品号不能为空");
        }
        SingleResponse<BOList> inquiryGoodsBOList = BoServiceUtils.findListByIn(ModelConst.T_INQUIRY_GOODS, "id", inquiryGoodsDto.getInquiryGoodsIdList());
        log.info("------------------------根据询价商品id获取询价商品列表：{}------------------------", JSONObject.toJSONString(inquiryGoodsBOList));
        return inquiryGoodsBOList;
    }

    /**
     * 通过询价单id查询全部报价明细
     *
     * @param inquiryDto 请求参数
     * @return 响应结果
     */
    @Path("quotationList")
    @POST
    @Operation(summary = "通过询价单id查询全部报价明细", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> quotationList(@Parameter InquiryDto inquiryDto) {
        if (StringUtils.isEmpty(inquiryDto.getInquiryId())) {
            return SingleResponse.error("-1", "询价单id不能为空");
        }
        // todo 是否不看供应商信息，根据组件属性来获取
        // 通过询价单id查询询价单信息
        SingleResponse<BOList> inquiryBOList = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY, "id", inquiryDto.getInquiryId());
        log.info("------------------------通过询价单id查询询价单信息：{}------------------------", JSONObject.toJSONString(inquiryBOList));
        Map<String, Object> inquiryMap = inquiryBOList.getData().getData().get(0);
        if ("0".equals(String.valueOf(inquiryMap.get("quote_hermetic_strategy")))
                || DateUtils.parseDate(String.valueOf(inquiryMap.get("expire"))).getTime() <= System.currentTimeMillis()) {
            // 通过询价单获取询价商品信息
            SingleResponse<BOList> inquiryGoodsBOList = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, "inquiry_id", inquiryDto.getInquiryId());
            log.info("------------------------通过询价单id查询询价商品信息：{}------------------------", JSONObject.toJSONString(inquiryGoodsBOList));
            List<String> inquiryGoodsIdList = Lists.newArrayList();
            inquiryGoodsBOList.getData().getData().forEach(map -> inquiryGoodsIdList.add(map.get("id").toString()));
            // 通过询价商品查询报价商品
            String[] columns = new String[]{"inquiry_goods_id", "quotation_goods_status"};
            Operator[] operators = new Operator[]{Operator.IN, Operator.IN};
            Object[] columnsVal = new Object[]{inquiryGoodsIdList, Arrays.asList(QuotationStatusEnum.QUOTATION_3_QUOTED.getCode(),
                    QuotationStatusEnum.QUOTATION_5_PICKETED.getCode(), QuotationStatusEnum.QUOTATION_6_CLOSE.getCode())};
            SingleResponse<BOList> quotationGoodsBOList = BoServiceUtils.findListByComplex(ModelConst.T_QUOTATION_GOODS, columns, columnsVal, operators);
            log.info("------------------------通过询价商品id查询报价商品信息：{}------------------------", JSONObject.toJSONString(quotationGoodsBOList));
            return quotationGoodsBOList;
        } else {
            // 密封报价，必须等到询价日期截止才能查看。先返回空
            BOList boList = new BOList();
            boList.setData(Lists.newArrayList());
            boList.setTotal(boList.getData().size());
            boList.setSchemaCode(ModelConst.T_QUOTATION_GOODS);
            return SingleResponse.of(boList);
        }
    }

    /**
     * 查看被邀请的供应商列表
     *
     * @return 供应商列表
     */
    @Path("invitedVendor")
    @POST
    @Operation(summary = "查看被邀请的供应商列表", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> invitedVendor() {
        SessionUser sessionUser = new SessionUser();
        String currentOrgID = sessionUser.getCurrentOrgID();
        List<String> customerIdList = OrgUtils.listVendorByCustomerId(currentOrgID);
        log.info("------------------------通过组织id查询被邀请的供应商id列表：{}------------------------", JSONObject.toJSONString(customerIdList));
        BOList boList = new BOList();
        if (CollectionUtils.isEmpty(customerIdList)) {
            boList.setData(Lists.newArrayList());
        } else {
            List<Map<String, Object>> orgList = Objects.requireNonNull(JdbcTemplateUtils.builder(AppConst.SYSTEM_MANAGEMENT, ModelConst.T_ORGANIZATION).selectField("id, parent_id, account_id, business_member_id, transaction_organization_id," +
                    "extends_attr, name, parent_name, business_member_name, description, role_names, organization_product_line, business_scope, license_code, credit_identifier," +
                    "legal_representative, registered_capital, memo, purchase_quota, attachment, platform, `virtual`, statement_cycle, reconciliation_day_strategy, payment_day_strategy," +
                    "small_scale, small_scale_rate, freight_ratio, pay_appoint_way, sales_area, major_brand, quotation_decimal_limit, level, enabled, connect, cellphone," +
                    "email, qq, platform_id, platform_name, invite_user, goods_automatic_matching, muti_org_id, org_attributeValue, org_attributeName"))
                    .in("id", customerIdList)
                    .queryForList();
            log.info("------------------------通过供应商id查询供应商组织信息：{}------------------------", JSONObject.toJSONString(orgList));
            if (CollectionUtils.isEmpty(orgList)) {
                boList.setData(Lists.newArrayList());
            } else {
                BoResultFormat.resultFormat(orgList, ModelConst.T_ORGANIZATION);
                boList.setData(orgList);
            }
        }

        boList.setTotal(boList.getData().size());
        boList.setSchemaCode(ModelConst.T_ORGANIZATION);
        return SingleResponse.of(boList);
    }

    /**
     * 更新询价单澄清状态和澄清数量
     *
     * @param inquiryGoods  询价商品
     * @param clarifyStatus 澄清状态
     */
    public void clarify(Map<String, Object> inquiryGoods, String clarifyStatus) {
        Map<String, Object> dataMap = Maps.newHashMap();
        dataMap.put("id", inquiryGoods.get("id"));
        dataMap.put("clarify_record", true);
        dataMap.put("clarify_status", clarifyStatus);
        AtomicInteger clarifyNumber = new AtomicInteger(1);
        if (inquiryGoods.get("clarify_number") != null) {
            clarifyNumber.set(new BigDecimal(inquiryGoods.get("clarify_number").toString()).intValue());
            clarifyNumber.getAndIncrement();
        }
        dataMap.put("clarify_number", clarifyNumber.intValue());
        SingleResponse<BO> inquiryGoodsResult = BoServiceUtils.updateMainBo(ModelConst.T_INQUIRY_GOODS, dataMap);
        log.info("------------------------更新询价商品成功，更新后结果：{}------------------------", JSONObject.toJSONString(inquiryGoodsResult));
    }

    /**
     * 获取表名称
     *
     * @param schemaCode 模型编码
     * @return 完整表名称
     */
    private static String getTableName(String schemaCode) {
        return tableHelper.getTableName(schemaCode);
    }

    /**
     * 需求转询价时获取需求池和需求商品信息，进行数据回写
     *
     * @param demandPoolId      需求池id
     * @param demandGoodsIdList 需求商品id列表
     * @return 询价单数据
     */
    private Inquiry getDemandData(String demandPoolId, List<String> demandGoodsIdList) {
        // 获取需求池信息
        SingleResponse<BOList> demandPool = BoServiceUtils.findListBySimple(ModelConst.T_DEMAND_POOL, "id", demandPoolId);
        log.info("------------------------根据需求池id获取需求池信息：{}------------------------", JSONObject.toJSONString(demandPool));
        // 获取需求商品信息
        SingleResponse<BOList> demandGoods = BoServiceUtils.findListByIn(ModelConst.T_DEMAND_GOODS, "id", demandGoodsIdList);
        log.info("------------------------根据需求商品id获取需求商品信息：{}------------------------", JSONObject.toJSONString(demandGoods));

        Inquiry inquiry = JSONUtil.toBean(JSONUtil.toJsonStr(demandPool.getData().getData().get(0)), Inquiry.class);
        List<InquiryGoods> inquiryGoodsList = Lists.newArrayList();
        JSONArray array;
        for (Map<String, Object> inquiryGoodsMap : demandGoods.getData().getData()) {
            InquiryGoods inquiryGoods = JSONUtil.toBean(JSONUtil.toJsonStr(inquiryGoodsMap), InquiryGoods.class);
            inquiryGoods.setDemand_goods_id(String.valueOf(inquiryGoodsMap.get("id")));
            inquiryGoods.setId(SchemaHelper.getId());
            array = inquiryGoods.getAttachment();
            if (array != null && array.size() > 0) {
                for (int i = 0; i < array.size(); i++) {
                    array.getJSONObject(i).put("url", "/api/file/download?refId=".concat(String.valueOf(array.getJSONObject(i).get("id"))));
                    array.getJSONObject(i).put("uid", String.valueOf(array.getJSONObject(i).get("id")));
                }
            }
            inquiryGoodsList.add(inquiryGoods);
        }
        log.info("------------------------需求商品转询价商品：{}------------------------", JSONObject.toJSONString(inquiryGoodsList));
        inquiry.setInquiryGoodsList(inquiryGoodsList);
        return inquiry;
    }

    /**
     * 再次询价时获取之前询价单和询价商品信息，进行数据回写
     *
     * @param inquiryId          询价单id
     * @param inquiryGoodsIdList 询价商品id集合
     */
    private Inquiry getInquiryData(String inquiryId, List<String> inquiryGoodsIdList) {
        // 获取询价单信息
        SingleResponse<BOList> inquiryData = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY, "id", inquiryId);
        log.info("------------------------根据询价单id获取询价单信息：{}------------------------", JSONObject.toJSONString(inquiryData));
        // 获取询价商品信息
        SingleResponse<BOList> inquiryGoodsData = BoServiceUtils.findListByIn(ModelConst.T_INQUIRY_GOODS, "id", inquiryGoodsIdList);
        log.info("------------------------根据询价商品id获取询价商品信息：{}------------------------", JSONObject.toJSONString(inquiryGoodsData));

        Inquiry inquiry = JSON.parseObject(JSON.toJSONString(inquiryData.getData().getData().get(0)), Inquiry.class);
        List<InquiryGoods> inquiryGoodsList = JSON.parseArray(JSON.toJSONString(inquiryGoodsData.getData().getData()), InquiryGoods.class);
        JSONArray array;
        for (InquiryGoods inquiryGoods : inquiryGoodsList) {
            inquiryGoods.setId(SchemaHelper.getId());
            array = inquiryGoods.getAttachment();
            if (array != null && array.size() > 0) {
                for (int i = 0; i < array.size(); i++) {
                    array.getJSONObject(i).put("url", "/api/file/download?refId=".concat(String.valueOf(array.getJSONObject(i).get("id"))));
                    array.getJSONObject(i).put("uid", String.valueOf(array.getJSONObject(i).get("id")));
                }
            }
        }
        inquiry.setInquiryGoodsList(inquiryGoodsList);
        return inquiry;
    }

    /**
     * 根据需求编号获取需求商品编号
     *
     * @param demandPoolIdList 需求商品id列表
     * @return 需求单id列表
     */
    private List<String> getDemandGoodsId(List<String> demandPoolIdList) {
        List<String> demandGoodsIdList = new ArrayList<>();
        demandPoolIdList.forEach(demandPoolId -> {
            SingleResponse<BOList> demandGoodsList = BoServiceUtils.findListBySimple(ModelConst.T_DEMAND_GOODS, ConfigConstant.DEMAND_POOL_ID, demandPoolId);
            for (int i = 0; i < demandGoodsList.getData().getTotal(); i++) {
                demandGoodsIdList.add(String.valueOf(demandGoodsList.getData().getData().get(i).get("id")));
            }
        });
        return demandGoodsIdList;
    }

    /**
     * 根据需求商品编号获取需求池编号
     *
     * @param demandGoodsIdList 需求商品id列表
     * @return 需求单id列表
     */
    private List<String> getDemandPoolId(List<String> demandGoodsIdList) {
        List<String> demandPoolIdList = new ArrayList<>();
        demandGoodsIdList.forEach(demandGoodsId -> {
            SingleResponse<BOList> demandPoolList = BoServiceUtils.findListBySimple(ModelConst.T_DEMAND_GOODS, "id", demandGoodsId);
            for (int i = 0; i < demandPoolList.getData().getTotal(); i++) {
                demandPoolIdList.add(String.valueOf(demandPoolList.getData().getData().get(i).get(ConfigConstant.DEMAND_POOL_ID)));
            }
        });
        return demandPoolIdList;
    }

    /**
     * 根据询价商品获取询价单id
     *
     * @param inquiryGoodsIdList 询价商品id列表
     * @return 询价单id列表
     */
    private List<String> getInquiryId(List<String> inquiryGoodsIdList) {
        List<String> inquiryIdList = new ArrayList<>();
        inquiryGoodsIdList.forEach(inquiryGoodsId -> {
            SingleResponse<BOList> inquiryList = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY_GOODS, "id", inquiryGoodsId);
            for (int i = 0; i < inquiryList.getData().getTotal(); i++) {
                inquiryIdList.add(String.valueOf(inquiryList.getData().getData().get(i).get(ConfigConstant.INQUIRY_ID)));
            }
        });
        return inquiryIdList;
    }

    /**
     * 询价单校验
     *
     * @param createInquiryDto 询价单信息
     * @throws InquiryException 询价异常
     */
    private void saveAndUpdateCheck(CreateInquiryDto createInquiryDto) throws InquiryException {
        // 询价单验证
        if (CollectionUtils.isEmpty(createInquiryDto.getC5uxuiw5i4qo())) {
            throw new InquiryException("-1", "请添加商品");
        }
        if (StringUtils.isEmpty(createInquiryDto.getName())) {
            throw new InquiryException("-2", "询价标题为必填项，请仔细填写。");
        }
        if (null == createInquiryDto.getExpire()) {
            throw new InquiryException("-3", "询价截止日期为必填项，请仔细填写。");
        }
        if (StringUtils.isEmpty(createInquiryDto.getVendor_scope())) {
            throw new InquiryException("-4", "询价方式为必填项，请仔细填写。");
        }
        if (StringUtils.isEmpty(createInquiryDto.getContacts())) {
            throw new InquiryException("-5", "联系人为必填项，请仔细填写。");
        }
        if (StringUtils.isEmpty(createInquiryDto.getMobile())) {
            throw new InquiryException("-6", "手机号为必填项，请仔细填写。");
        }
        if (DateUtils.parseDate(createInquiryDto.getExpire(), "yyyy-MM-dd hh:mm:ss").getTime() <= System.currentTimeMillis()) {
            throw new InquiryException("-7", "询价截止时间不能小于等于当前时间");
        }
        if (DateUtils.parseDate(createInquiryDto.getQuote_min_time_strategy(), "yyyy-MM-dd hh:mm:ss").getTime() > DateUtils.addDays(DateUtils.parseDate(createInquiryDto.getQuote_min_time_strategy(), "yyyy-MM-dd hh:mm:ss"), 365).getTime()) {
            throw new InquiryException("-8", "报价有效期不能大于截止日期365天");
        }
        // 询价商品验证
        for (CreateInquiryGoodsDto createInquiryGoodsDto : createInquiryDto.getC5uxuiw5i4qo()) {
            if (StringUtils.isEmpty(createInquiryGoodsDto.getName())) {
                throw new InquiryException("-9", "商品名称为必填项，请仔细填写。");
            }
            if (StringUtils.isEmpty(createInquiryGoodsDto.getModel())) {
                throw new InquiryException("-10", "型号为必填项，请仔细填写。");
            }
            if (StringUtils.isEmpty(createInquiryGoodsDto.getBrand())) {
                throw new InquiryException("-11", "品牌为必填项，请仔细填写。");
            }
            if (StringUtils.isEmpty(createInquiryGoodsDto.getAddress())) {
                throw new InquiryException("-12", "收货地址为必填项，请仔细填写。");
            }
            if (null == createInquiryGoodsDto.getNum()) {
                throw new InquiryException("-13", "数量为必填项，请仔细填写。");
            }
            if (null == createInquiryGoodsDto.getUnit()) {
                throw new InquiryException("-14", "单位为必填项，请仔细填写。");
            }
            if (createInquiryGoodsDto.getNum().compareTo(BigDecimal.ZERO) <= 0) {
                throw new InquiryException("-15", "商品数量不等小于或等于0");
            }
            if (null != createInquiryGoodsDto.getPackage_num()) {
                if (createInquiryGoodsDto.getPackage_num().compareTo(BigDecimal.ZERO) <= 0) {
                    throw new InquiryException("-16", "包装商品数量不能小于或等于0");
                }
            }
            if (StringUtils.isEmpty(createInquiryGoodsDto.getCategory_id())) {
                throw new InquiryException("-17", "请选择平台类目");
            }
        }
    }

    /**
     * 根据组织sku或型号查询报价
     *
     * @param sku            物料号
     * @param model          型号
     * @param organizationId 供应商
     * @return 报价列表
     */
    private List<Map<String, Object>> quotationGoodsByModelOrSkuAndOrganizationId(String sku, String model, SelectorFormat organizationId) {
        Map<String, Object> parameter = Maps.newHashMap();
        // 拼接sql
        StringBuilder querySql = new StringBuilder();// 获取总数
        querySql.append("select qg.* from \n");
        querySql.append(quotationGoodsName).append(" as qg\n");
        querySql.append("left join ").append(inquiryGoodsName).append(" as ig on qg.inquiry_goods_id = ig.id\n");
        querySql.append("left join ").append(inquiryName).append(" as i on ig.inquiry_id = i.id\n");
        querySql.append("where 1 = 1\n");
        querySql.append("and ((ig.sku = :sku and ig.sku <> '') or ig.model = :model)\n");
        parameter.put("sku", sku);
        parameter.put("model", model);
        querySql.append("and i.organization_id -> '$.id' = :organizationId\n");
        parameter.put("organizationId", organizationId.getId());
        querySql.append("and ig.deleted = 0 and qg.deleted = 0 and qg.picketage = 1\n");
        querySql.append("ORDER BY qg.price asc\n");

        log.info("totalSql = {}, parameters = {}", querySql, JSONObject.toJSONString(parameter));

        List<Map<String, Object>> sqlResult = jdbcTemplate.queryForList(querySql.toString(), parameter);
        log.info("------------------------sqlResult：{}------------------------", JSONObject.toJSONString(sqlResult));
        return sqlResult;
    }

    /**
     * 根据组织sku和区域查询报价
     *
     * @param sku            物料号
     * @param area           区域
     * @param organizationId 供应商
     * @return 报价列表
     */
    private List<Map<String, Object>> quotationGoodsByAreaAndSkuAndOrganizationId(String sku, String area, SelectorFormat organizationId) {
        // 获取表名
        Map<String, Object> parameter = Maps.newHashMap();
        // 拼接sql
        StringBuilder querySql = new StringBuilder();// 获取总数
        querySql.append("select qg.* from \n");
        querySql.append(quotationGoodsName).append(" as qg\n");
        querySql.append("left join ").append(inquiryGoodsName).append(" as ig on qg.inquiry_goods_id = ig.id\n");
        querySql.append("left join ").append(inquiryName).append(" as i on ig.inquiry_id = i.id\n");
        querySql.append("where 1 = 1\n");
        querySql.append("and ig.sku = :sku\n");
        parameter.put("sku", sku);
        querySql.append("and ig.area = :area\n");
        parameter.put("area", area);
        querySql.append("and i.organization_id = :organizationId\n");
        parameter.put("organizationId", organizationId);
        querySql.append("and ig.deleted = 0 and qg.deleted = 0 and qg.picketage = 1\n");
        querySql.append("ORDER BY qg.price asc\n");
        log.info("totalSql = {}, parameters = {}", querySql, JSONObject.toJSONString(parameter));

        List<Map<String, Object>> sqlResult = jdbcTemplate.queryForList(querySql.toString(), parameter);
        log.info("------------------------sqlResult：{}------------------------", JSONObject.toJSONString(sqlResult));
        return sqlResult;
    }

    /**
     * 自动匹配报价
     *
     * @param inquiry 询价单信息
     */
    private void autoMatchQuotation(CreateInquiryDto inquiry) {
        log.info("------------------------》》进入自动匹配报价《《------------------------");
        SingleResponse<List<BO>> quotationResult;
        SingleResponse<BO> updateQuotationResult;
        Map<String, Object> quotationMap;
        List<QuotationGoodsDto> quotationGoodsDtoList = Lists.newArrayList();
        // todo 获取牧原集团的所有组织信息
        for (CreateInquiryGoodsDto inquiryGoods : inquiry.getC5uxuiw5i4qo()) {
            /*
             * 询价商品是牧原集团组织的，则用新的匹配规则
             * 企业采购目录中历史定标的报价商品该条商品的询价商品料号以及询价商品区域，
             * 两个参数必须同时等于，将企业采购目录中的该条报价信息，自动作为新的报价
             * 两个之中任何一个为空则不匹配
             * */
            // todo 判断是不是牧原组织，先测试接口，数据写死
            List<Map<String, Object>> sqlResult = quotationGoodsByModelOrSkuAndOrganizationId(inquiryGoods.getSku(), inquiryGoods.getModel(), inquiry.getOrganization_id().get(0));
            log.info("-----------------获取自动报价数据:{}------------", JSONObject.toJSONString(sqlResult));
            List<QuotationGoodsVo> quotationList = JSONUtil.toList(JSONUtil.parseArray(sqlResult), QuotationGoodsVo.class);
            quotationList = quotationList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(QuotationGoodsVo::getVendor_organization_name))), ArrayList::new));
            if (quotationList != null && !quotationList.isEmpty()) {
                for (QuotationGoodsVo quotationGoodsVo : quotationList) {
                    if (quotationGoodsVo.getExpire().getTime() > System.currentTimeMillis()) {
                        // 参与报价
                        InquiryGoodsDto inquiryGoodsDto = new InquiryGoodsDto();
                        // 设置供应商id
                        String orgId = quotationGoodsVo.getVendor_organization_id().get(0).getId();
                        inquiryGoodsDto.setOrgId(orgId);
                        inquiryGoodsDto.setIsVirtual(false);
                        inquiryGoodsDto.setInquiryGoodsIdList(Collections.singletonList(inquiryGoods.getId()));
                        quotationResult = quotationService.batchParticipation(inquiryGoodsDto);
                        quotationMap = quotationResult.getData().get(0).getData();
                        // 修改报价
                        if (quotationMap != null) {
                            quotationMap.put("name", quotationGoodsVo.getName());
                            quotationMap.put("brand", quotationGoodsVo.getBrand());
                            quotationMap.put("model", quotationGoodsVo.getModel());
                            quotationMap.put("spec", quotationGoodsVo.getSpec());
                            quotationMap.put("num", quotationGoodsVo.getNum());
                            quotationMap.put("package_num", quotationGoodsVo.getPackage_num());
                            quotationMap.put("package_unit", quotationGoodsVo.getPackage_unit());
                            quotationMap.put("quotation_goods_status", QuotationStatusEnum.QUOTATION_0_NEW.getCode());
                            quotationMap.put("org_category_name", quotationGoodsVo.getOrg_category_name());
                            quotationMap.put("auto_quotation", quotationGoodsVo.getAuto_quotation());
                            quotationMap.put("sku", quotationGoodsVo.getSku());
                            quotationMap.put("bar_code", quotationGoodsVo.getBar_code());
                            quotationMap.put("delivery", quotationGoodsVo.getDelivery() == null ? 0 : quotationGoodsVo.getDelivery());
                            quotationMap.put("expire", quotationGoodsVo.getExpire());
                            quotationMap.put("address", quotationGoodsVo.getAddress());
                            quotationMap.put("description", quotationGoodsVo.getDescription());
                            // region 报价金额
                            quotationMap.put("tax_rate", quotationGoodsVo.getTax_rate());
                            quotationMap.put("tax_rate_freight", quotationGoodsVo.getTax_rate_freight());
                            quotationMap.put("pretax_freight", quotationGoodsVo.getPretax_freight());
                            quotationMap.put("pretax_price", quotationGoodsVo.getPretax_price());
                            quotationMap.put("price", quotationGoodsVo.getPrice());
                            quotationMap.put("pretax_total", quotationGoodsVo.getPretax_total());
                            quotationMap.put("total", quotationGoodsVo.getTotal());
                            quotationMap.put("amount", quotationGoodsVo.getAmount());
                            quotationMap.put("tax_payable", quotationGoodsVo.getTax_payable());
                            quotationMap.put("pretax_amount", quotationGoodsVo.getPretax_amount());
                            quotationMap.put("freight", quotationGoodsVo.getFreight());
                            quotationMap.put("tax_payable_freight", quotationGoodsVo.getTax_payable_freight());
                            // endregion
                            quotationMap.put("attachment", quotationGoodsVo.getAttachment());
                            quotationMap.put("maximum", quotationGoodsVo.getMaximum());
                            quotationMap.put("min_order", quotationGoodsVo.getMin_order());
                            quotationMap.put("remark_message", quotationGoodsVo.getRemark_message());
                            quotationMap.put("source", QuotationSourceEnum.AutoQuotation.name());
                            // 平台报价运费通过手动输入
                            if ("1".equals(quotationMap.get("auto_quotation"))) {
                                quotationMap.put("freight", quotationGoodsVo.getFreight());
                            }
                            // todo 更新时会提示拥有者和拥有者部门不匹配，先remove掉
                            quotationMap = quotationService.formatQuotationGoods(quotationMap);
                            updateQuotationResult = BoServiceUtils.updateMainBo(ModelConst.T_QUOTATION_GOODS, quotationMap);
                            QuotationGoodsDto quotationGoodsDto = new QuotationGoodsDto();
                            quotationGoodsDto.setQuotationId(updateQuotationResult.getData().getBizObjectId());
                            quotationGoodsDto.setInquiryId(String.valueOf(updateQuotationResult.getData().getData().get("inquiry_id")));
                            quotationGoodsDtoList.add(quotationGoodsDto);
                        }
                    }
                }
            }
            if (!quotationGoodsDtoList.isEmpty()) {
                quotationService.batchCommit(quotationGoodsDtoList);
            }
        }
    }

    /**
     * 创建澄清记录数据
     *
     * @param clarifyMap    澄清记录
     * @param clarifyDto    澄清内容
     * @param clarifyStatus 澄清状态
     */
    public String buildClarifyMap(Map<String, Object> clarifyMap, InquiryGoodsClarifyDto clarifyDto, String clarifyStatus) {
        SessionUser sessionUser = new SessionUser();
        boolean zc = false;
        // 获取当前用户的角色，是否有驻场角色
        UserDto userDto = sessionUser.get();
        List<String> roleIds = Arrays.asList(userDto.getRole_ids().split(","));
        Set<String> roleNames = RoleUtils.listRoleNames(roleIds);
        for (String roleName : roleNames) {
            if (PlatformConst.ROLE_PM_ZC.equals(roleName) || PlatformConst.ROLE_CUSTOMER_ZC.equals(roleName)) {
                zc = true;
                break;
            }
        }
        // 如果是驻场角色，设置澄清状态为供应商待澄清
        if (zc) {
            clarifyStatus = ClarifyStatusEnum.VENDOR_WAIT_2_CLARIFY.getCode();
        } else {
            if (sessionUser.isVendor()) {
                clarifyStatus = ClarifyStatusEnum.ZC_WAIT_1_CLARIFY.getCode();
                clarifyMap.put("vendor_id", userDto.getOrganization_id().get(0));
            } else if (sessionUser.isCustomer()) {
                clarifyStatus = ClarifyStatusEnum.ZC_WAIT_1_CLARIFY.getCode();
                clarifyMap.put("customer_id", userDto.getOrganization_id().get(0));
            }
        }
        log.info("------------------------clarifyStatus：{}------------------------", clarifyStatus);
        clarifyMap.put("inquiry_goods_id", clarifyDto.getInquiryGoodsId());
        clarifyMap.put("clarify_tips", clarifyDto.getClarifyTips());
        clarifyMap.put("attachment", clarifyDto.getAttachment());
        clarifyMap.put("member_id", sessionUser.getUserFormat(userDto.getId(), userDto.getFullname()));
        clarifyMap.put("member_name", userDto.getFullname());
        clarifyMap.put("organization_name", userDto.getOrganization_name());
        return clarifyStatus;
    }

    /**
     * 创建询价单定时任务
     *
     * @param inquiryResultMap 询价单信息
     */
    private void inquiryCloseScheduler(Map<String, Object> inquiryResultMap) {
        TriggerMetaDto metaDto = new TriggerMetaDto();
        metaDto.setAppCode(AppConst.SOURCING_CENTER);
        metaDto.setUrl(ScheduleUrlConst.UPDATE_EXPIRED_INQUIRY_URL);
        JSONObject body = new JSONObject();
        body.put("inquiryId", inquiryResultMap.get("id"));
        metaDto.setBody(body.toJSONString());
        metaDto.setDesc("询价单定时触发器");
        // 获取询价截止日期
        String expire = String.valueOf(inquiryResultMap.get("expire"));
        //Date 转localDateTime
        LocalDateTime localDateTime = DateUtils.parseDate(expire).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        //时间转Cron表达式
        String cron = DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy").format(localDateTime);
        log.warn("询价创建定时生成Cron表达式：id:{} , Date：{}，LocalDate:{} ,Cron表达式：{}", inquiryResultMap.get("id"), inquiryResultMap.get("expire"), localDateTime, cron);
        metaDto.setCron(cron);
        String url = HttpClients.getUrl(AppConst.SYSTEM_MANAGEMENT, ServiceUrlConst.ADD_JOB_URL);
        HttpClients.execute(url, metaDto);
    }

    /**
     * 小规模供应商价格转换
     *
     * @param quotationGoodsList 报价商品列表
     * @return 转化后的报价商品列表
     */
    public List<Map<String, Object>> conversion(List<Map<String, Object>> quotationGoodsList) {
        for (Map<String, Object> quotationGoods : quotationGoodsList) {
            // 只有采购税率字段不为空时才需要转换
            if (quotationGoods.get("purchase_tax_rate") == null) {
                continue;
            }
            BigDecimal freight = quotationGoods.get("freight") == null ? BigDecimal.ZERO : (BigDecimal) quotationGoods.get("freight");
            BigDecimal purchaseTaxRate = (BigDecimal) quotationGoods.get("purchase_tax_rate");

            // 根据未税单价和采购税率计算含税单价
            BigDecimal price = TaxRateUtils.calculateTaxAfter((BigDecimal) quotationGoods.get("pretax_price"), purchaseTaxRate);

            // 根据未税小计和采购税率计算含税小计
            BigDecimal total = TaxRateUtils.calculateTaxAfter((BigDecimal) quotationGoods.get("pretax_total"), purchaseTaxRate);

            // 小计需要四舍五入
            total = BigDecimalUtils.round(total, 2);

            // 计算税额，税额 = 含税小计 - 未税小计
            BigDecimal taxPayable = BigDecimalUtils.sub(total, (BigDecimal) quotationGoods.get("pretax_total"));

            // 计算含税总计，含税总计 = 含税小计 + 运费
            BigDecimal amount = BigDecimalUtils.add(total, freight);

            // 重新赋值
            quotationGoods.put("price", price);
            quotationGoods.put("total", total);
            quotationGoods.put("tax_payable", taxPayable);
            quotationGoods.put("amount", amount);
            quotationGoods.put("tax_rate", purchaseTaxRate);
        }
        return quotationGoodsList;
    }
}
